diff options
author | Cy Schubert <cy@FreeBSD.org> | 2025-04-25 14:41:24 +0000 |
---|---|---|
committer | Cy Schubert <cy@FreeBSD.org> | 2025-04-25 14:41:24 +0000 |
commit | 44bab727dfe28451b777dc9e47db4f748b709182 (patch) | |
tree | b8abab888105843c7f120357a1e010bfd6d5ef8c | |
parent | 0a6d797cf6eb751d7eb613900cd19803e05d905f (diff) |
223 files changed, 19044 insertions, 7586 deletions
diff --git a/Makefile.in b/Makefile.in index c262250ca2c5..463cdac286e1 100644 --- a/Makefile.in +++ b/Makefile.in @@ -179,11 +179,11 @@ testcode/unitlruhash.c testcode/unitmain.c testcode/unitmsgparse.c \ testcode/unitneg.c testcode/unitregional.c testcode/unitslabhash.c \ testcode/unitverify.c testcode/readhex.c testcode/testpkts.c testcode/unitldns.c \ testcode/unitecs.c testcode/unitauth.c testcode/unitzonemd.c \ -testcode/unittcpreuse.c testcode/unitdoq.c +testcode/unittcpreuse.c testcode/unitdoq.c testcode/unitinfra.c UNITTEST_OBJ=unitanchor.lo unitdname.lo unitlruhash.lo unitmain.lo \ unitmsgparse.lo unitneg.lo unitregional.lo unitslabhash.lo unitverify.lo \ readhex.lo testpkts.lo unitldns.lo unitecs.lo unitauth.lo unitzonemd.lo \ -unittcpreuse.lo unitdoq.lo +unittcpreuse.lo unitdoq.lo unitinfra.lo UNITTEST_OBJ_LINK=$(UNITTEST_OBJ) worker_cb.lo $(COMMON_OBJ) $(SLDNS_OBJ) \ $(COMPAT_OBJ) DAEMON_SRC=daemon/acl_list.c daemon/cachedump.c daemon/daemon.c \ @@ -509,10 +509,15 @@ util/configlexer.c: $(srcdir)/util/configlexer.lex util/configparser.h fi @if test ! -f $@; then echo "No $@ : need flex and bison to compile from source repository"; exit 1; fi -util/configparser.c util/configparser.h: $(srcdir)/util/configparser.y +# Builds both util/configparser.c and util/configparser.h. +# To avoid double-building we split one target out. +util/configparser.c: $(srcdir)/util/configparser.y @-if test ! -d util; then $(INSTALL) -d util; fi $(YACC) -d -o util/configparser.c $(srcdir)/util/configparser.y +util/configparser.h: util/configparser.c + touch $@ + clean: rm -f *.o *.d *.lo *~ tags rm -f unbound$(EXEEXT) unbound-checkconf$(EXEEXT) unbound-host$(EXEEXT) unbound-control$(EXEEXT) unbound-anchor$(EXEEXT) unbound-control-setup libunbound.la unbound.h @@ -876,7 +881,7 @@ view.lo view.o: $(srcdir)/services/view.c config.h $(srcdir)/services/view.h $(s $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/services/localzone.h $(srcdir)/util/storage/dnstree.h \ $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \ - $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h + $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/util/config_file.h $(srcdir)/respip/respip.h rpz.lo rpz.o: $(srcdir)/services/rpz.c config.h $(srcdir)/services/rpz.h $(srcdir)/services/localzone.h \ $(srcdir)/util/rbtree.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/storage/dnstree.h \ $(srcdir)/util/module.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/msgreply.h \ @@ -972,7 +977,7 @@ fptr_wlist.lo fptr_wlist.o: $(srcdir)/util/fptr_wlist.c config.h $(srcdir)/util/ $(srcdir)/validator/val_nsec3.h $(srcdir)/validator/val_sigcrypt.h $(srcdir)/validator/val_kentry.h \ $(srcdir)/validator/val_neg.h $(srcdir)/validator/autotrust.h $(srcdir)/libunbound/libworker.h \ $(srcdir)/libunbound/context.h $(srcdir)/util/alloc.h $(srcdir)/libunbound/unbound-event.h \ - $(srcdir)/libunbound/worker.h + $(srcdir)/libunbound/worker.h $(srcdir)/daemon/remote.h locks.lo locks.o: $(srcdir)/util/locks.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h log.lo log.o: $(srcdir)/util/log.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h $(srcdir)/sldns/sbuffer.h mini_event.lo mini_event.o: $(srcdir)/util/mini_event.c config.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h \ @@ -1059,7 +1064,7 @@ tube.lo tube.o: $(srcdir)/util/tube.c config.h $(srcdir)/util/tube.h $(srcdir)/u $(srcdir)/libunbound/unbound.h $(srcdir)/respip/respip.h $(srcdir)/util/ub_event.h ub_event.lo ub_event.o: $(srcdir)/util/ub_event.c config.h $(srcdir)/util/ub_event.h $(srcdir)/util/log.h \ $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ - $(srcdir)/util/tube.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h + $(srcdir)/util/tube.h $(srcdir)/util/mini_event.h $(srcdir)/util/rbtree.h $(srcdir)/daemon/remote.h ub_event_pluggable.lo ub_event_pluggable.o: $(srcdir)/util/ub_event_pluggable.c config.h $(srcdir)/util/ub_event.h \ $(srcdir)/libunbound/unbound-event.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \ $(srcdir)/util/log.h $(srcdir)/util/fptr_wlist.h \ @@ -1256,6 +1261,7 @@ unitzonemd.lo unitzonemd.o: $(srcdir)/testcode/unitzonemd.c config.h $(srcdir)/u $(srcdir)/validator/val_anchor.h unittcpreuse.lo unittcpreuse.o: $(srcdir)/testcode/unittcpreuse.c config.h $(srcdir)/services/outside_network.h \ $(srcdir)/util/random.h +unitinfra.lo unitinfra.o: $(srcdir)/testcode/unitinfra.c config.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/iterator/iterator.h acl_list.lo acl_list.o: $(srcdir)/daemon/acl_list.c config.h $(srcdir)/daemon/acl_list.h \ $(srcdir)/util/storage/dnstree.h $(srcdir)/util/rbtree.h $(srcdir)/services/view.h $(srcdir)/util/locks.h \ $(srcdir)/util/log.h $(srcdir)/util/regional.h $(srcdir)/util/config_file.h $(srcdir)/util/net_help.h \ @@ -1307,7 +1313,10 @@ remote.lo remote.o: $(srcdir)/daemon/remote.c config.h $(srcdir)/daemon/remote.h $(srcdir)/validator/val_anchor.h $(srcdir)/iterator/iterator.h $(srcdir)/services/outbound_list.h \ $(srcdir)/iterator/iter_fwd.h $(srcdir)/iterator/iter_hints.h $(srcdir)/iterator/iter_delegpt.h \ $(srcdir)/services/outside_network.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/parseutil.h \ - $(srcdir)/sldns/wire2str.h $(srcdir)/util/edns.h + $(srcdir)/sldns/wire2str.h $(srcdir)/util/edns.h \ + $(srcdir)/util/locks.h $(srcdir)/util/ub_event.h \ + $(srcdir)/util/tcp_conn_limit.h $(srcdir)/util/edns.h $(srcdir)/validator/val_neg.h \ + $(srcdir)/iterator/iter_utils.h $(srcdir)/iterator/iter_donotq.h $(srcdir)/iterator/iter_priv.h stats.lo stats.o: $(srcdir)/daemon/stats.c config.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \ $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \ diff --git a/ax_build_date_epoch.m4 b/ax_build_date_epoch.m4 new file mode 100644 index 000000000000..dbecb067a8cb --- /dev/null +++ b/ax_build_date_epoch.m4 @@ -0,0 +1,70 @@ +# =========================================================================== +# https://www.gnu.org/software/autoconf-archive/ax_build_date_epoch.html +# =========================================================================== +# +# SYNOPSIS +# +# AX_BUILD_DATE_EPOCH(VARIABLE[, FORMAT[, ACTION-IF-FAIL]]) +# +# DESCRIPTION +# +# Sets VARIABLE to a string representing the current time. It is +# formatted according to FORMAT if specified, otherwise it is formatted as +# the number of seconds (excluding leap seconds) since the UNIX epoch (01 +# Jan 1970 00:00:00 UTC). +# +# If the SOURCE_DATE_EPOCH environment variable is set, it uses the value +# of that variable instead of the current time. See +# https://reproducible-builds.org/specs/source-date-epoch). If +# SOURCE_DATE_EPOCH is set but cannot be properly interpreted as a UNIX +# timestamp, then execute ACTION-IF-FAIL if specified, otherwise error. +# +# VARIABLE is AC_SUBST-ed. +# +# LICENSE +# +# Copyright (c) 2016 Eric Bavier <bavier@member.fsf.org> +# +# This program is free software: you can redistribute it and/or modify it +# under the terms of the GNU General Public License as published by the +# Free Software Foundation, either version 3 of the License, or (at your +# option) any later version. +# +# This program is distributed in the hope that it will be useful, but +# WITHOUT ANY WARRANTY; without even the implied warranty of +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General +# Public License for more details. +# +# You should have received a copy of the GNU General Public License along +# with this program. If not, see <https://www.gnu.org/licenses/>. +# +# As a special exception, the respective Autoconf Macro's copyright owner +# gives unlimited permission to copy, distribute and modify the configure +# scripts that are the output of Autoconf when processing the Macro. You +# need not follow the terms of the GNU General Public License when using +# or distributing such scripts, even though portions of the text of the +# Macro appear in them. The GNU General Public License (GPL) does govern +# all other use of the material that constitutes the Autoconf Macro. +# +# This special exception to the GPL applies to versions of the Autoconf +# Macro released by the Autoconf Archive. When you make and distribute a +# modified version of the Autoconf Macro, you may extend this special +# exception to the GPL to apply to your modified version as well. + +#serial 2 + +AC_DEFUN([AX_BUILD_DATE_EPOCH], +[dnl +AC_MSG_CHECKING([for build time]) +ax_date_fmt="m4_default($2,%s)" +AS_IF([test x"$SOURCE_DATE_EPOCH" = x], + [$1=`date "+$ax_date_fmt"`], + [ax_build_date=`date -u -d "@$SOURCE_DATE_EPOCH" "+$ax_date_fmt" 2>/dev/null \ + || date -u -r "$SOURCE_DATE_EPOCH" "+$ax_date_fmt" 2>/dev/null` + AS_IF([test x"$ax_build_date" = x], + [m4_ifval([$3], + [$3], + [AC_MSG_ERROR([malformed SOURCE_DATE_EPOCH])])], + [$1=$ax_build_date])]) +AC_MSG_RESULT([$$1]) +])dnl AX_BUILD_DATE_EPOCH diff --git a/cachedb/cachedb.c b/cachedb/cachedb.c index 0329f8458bd7..bdb1754e42d2 100644 --- a/cachedb/cachedb.c +++ b/cachedb/cachedb.c @@ -47,6 +47,7 @@ #include "util/regional.h" #include "util/net_help.h" #include "util/config_file.h" +#include "util/data/dname.h" #include "util/data/msgreply.h" #include "util/data/msgencode.h" #include "services/cache/dns.h" @@ -341,6 +342,7 @@ calc_hash(struct query_info* qinfo, struct module_env* env, char* buf, /* copy the hash info into the clear buffer */ if(clen + qinfo->qname_len < sizeof(clear)) { memmove(clear+clen, qinfo->qname, qinfo->qname_len); + query_dname_tolower(clear+clen); clen += qinfo->qname_len; } if(clen + 4 < sizeof(clear)) { @@ -755,7 +757,8 @@ cachedb_intcache_store(struct module_qstate* qstate, int msg_expired) } (void)dns_cache_store(qstate->env, &qstate->qinfo, qstate->return_msg->rep, 0, qstate->prefetch_leeway, 0, - qstate->region, store_flags, qstate->qstarttime); + qstate->region, store_flags, qstate->qstarttime, + qstate->is_valrec); if(serve_expired && msg_expired) { if(qstate->env->cfg->serve_expired_client_timeout) { /* No expired response from the query state, the diff --git a/cachedb/redis.c b/cachedb/redis.c index 68c033535a69..3dfa95859eb8 100644 --- a/cachedb/redis.c +++ b/cachedb/redis.c @@ -52,19 +52,38 @@ #include "hiredis/hiredis.h" struct redis_moddata { - redisContext** ctxs; /* thread-specific redis contexts */ - int numctxs; /* number of ctx entries */ - const char* server_host; /* server's IP address or host name */ - int server_port; /* server's TCP port */ - const char* server_path; /* server's unix path, or "", NULL if unused */ - const char* server_password; /* server's AUTH password, or "", NULL if unused */ - struct timeval command_timeout; /* timeout for commands */ - struct timeval connect_timeout; /* timeout for connect */ - int logical_db; /* the redis logical database to use */ + /* thread-specific redis contexts */ + redisContext** ctxs; + redisContext** replica_ctxs; + /* number of ctx entries */ + int numctxs; + /* server's IP address or host name */ + const char* server_host; + const char* replica_server_host; + /* server's TCP port */ + int server_port; + int replica_server_port; + /* server's unix path, or "", NULL if unused */ + const char* server_path; + const char* replica_server_path; + /* server's AUTH password, or "", NULL if unused */ + const char* server_password; + const char* replica_server_password; + /* timeout for commands */ + struct timeval command_timeout; + struct timeval replica_command_timeout; + /* timeout for connection setup */ + struct timeval connect_timeout; + struct timeval replica_connect_timeout; + /* the redis logical database to use */ + int logical_db; + int replica_logical_db; + /* if the SET with EX command is supported */ + int set_with_ex_available; }; static redisReply* redis_command(struct module_env*, struct cachedb_env*, - const char*, const uint8_t*, size_t); + const char*, const uint8_t*, size_t, int); static void moddata_clean(struct redis_moddata** moddata) { @@ -78,21 +97,30 @@ moddata_clean(struct redis_moddata** moddata) { } free((*moddata)->ctxs); } + if((*moddata)->replica_ctxs) { + int i; + for(i = 0; i < (*moddata)->numctxs; i++) { + if((*moddata)->replica_ctxs[i]) + redisFree((*moddata)->replica_ctxs[i]); + } + free((*moddata)->replica_ctxs); + } free(*moddata); *moddata = NULL; } static redisContext* -redis_connect(const struct redis_moddata* moddata) +redis_connect(const char* host, int port, const char* path, + const char* password, int logical_db, + const struct timeval connect_timeout, + const struct timeval command_timeout) { redisContext* ctx; - if(moddata->server_path && moddata->server_path[0]!=0) { - ctx = redisConnectUnixWithTimeout(moddata->server_path, - moddata->connect_timeout); + if(path && path[0]!=0) { + ctx = redisConnectUnixWithTimeout(path, connect_timeout); } else { - ctx = redisConnectWithTimeout(moddata->server_host, - moddata->server_port, moddata->connect_timeout); + ctx = redisConnectWithTimeout(host, port, connect_timeout); } if(!ctx || ctx->err) { const char *errstr = "out of memory"; @@ -101,13 +129,13 @@ redis_connect(const struct redis_moddata* moddata) log_err("failed to connect to redis server: %s", errstr); goto fail; } - if(redisSetTimeout(ctx, moddata->command_timeout) != REDIS_OK) { - log_err("failed to set redis timeout"); + if(redisSetTimeout(ctx, command_timeout) != REDIS_OK) { + log_err("failed to set redis timeout, %s", ctx->errstr); goto fail; } - if(moddata->server_password && moddata->server_password[0]!=0) { + if(password && password[0]!=0) { redisReply* rep; - rep = redisCommand(ctx, "AUTH %s", moddata->server_password); + rep = redisCommand(ctx, "AUTH %s", password); if(!rep || rep->type == REDIS_REPLY_ERROR) { log_err("failed to authenticate with password"); freeReplyObject(rep); @@ -115,18 +143,25 @@ redis_connect(const struct redis_moddata* moddata) } freeReplyObject(rep); } - if(moddata->logical_db > 0) { + if(logical_db > 0) { redisReply* rep; - rep = redisCommand(ctx, "SELECT %d", moddata->logical_db); + rep = redisCommand(ctx, "SELECT %d", logical_db); if(!rep || rep->type == REDIS_REPLY_ERROR) { log_err("failed to set logical database (%d)", - moddata->logical_db); + logical_db); freeReplyObject(rep); goto fail; } freeReplyObject(rep); } - verbose(VERB_OPS, "Connection to Redis established"); + if(verbosity >= VERB_OPS) { + char port_str[6+1]; + port_str[0] = ' '; + (void)snprintf(port_str+1, sizeof(port_str)-1, "%d", port); + verbose(VERB_OPS, "Connection to Redis established (%s%s)", + path&&path[0]!=0?path:host, + path&&path[0]!=0?"":port_str); + } return ctx; fail: @@ -135,6 +170,14 @@ fail: return NULL; } +static void +set_timeout(struct timeval* timeout, int value, int explicit_value) +{ + int v = explicit_value != 0 ? explicit_value : value; + timeout->tv_sec = v / 1000; + timeout->tv_usec = (v % 1000) * 1000; +} + static int redis_init(struct module_env* env, struct cachedb_env* cachedb_env) { @@ -149,57 +192,98 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env) goto fail; } moddata->numctxs = env->cfg->num_threads; - moddata->ctxs = calloc(env->cfg->num_threads, sizeof(redisContext*)); - if(!moddata->ctxs) { - log_err("out of memory"); - goto fail; - } - /* note: server_host is a shallow reference to configured string. - * we don't have to free it in this module. */ + /* note: server_host and similar string configuration options are + * shallow references to configured strings; we don't have to free them + * in this module. */ moddata->server_host = env->cfg->redis_server_host; + moddata->replica_server_host = env->cfg->redis_replica_server_host; + moddata->server_port = env->cfg->redis_server_port; + moddata->replica_server_port = env->cfg->redis_replica_server_port; + moddata->server_path = env->cfg->redis_server_path; + moddata->replica_server_path = env->cfg->redis_replica_server_path; + moddata->server_password = env->cfg->redis_server_password; - moddata->command_timeout.tv_sec = env->cfg->redis_timeout / 1000; - moddata->command_timeout.tv_usec = - (env->cfg->redis_timeout % 1000) * 1000; - moddata->connect_timeout.tv_sec = env->cfg->redis_timeout / 1000; - moddata->connect_timeout.tv_usec = - (env->cfg->redis_timeout % 1000) * 1000; - if(env->cfg->redis_command_timeout != 0) { - moddata->command_timeout.tv_sec = - env->cfg->redis_command_timeout / 1000; - moddata->command_timeout.tv_usec = - (env->cfg->redis_command_timeout % 1000) * 1000; + moddata->replica_server_password = env->cfg->redis_replica_server_password; + + set_timeout(&moddata->command_timeout, + env->cfg->redis_timeout, + env->cfg->redis_command_timeout); + set_timeout(&moddata->replica_command_timeout, + env->cfg->redis_replica_timeout, + env->cfg->redis_replica_command_timeout); + set_timeout(&moddata->connect_timeout, + env->cfg->redis_timeout, + env->cfg->redis_connect_timeout); + set_timeout(&moddata->replica_connect_timeout, + env->cfg->redis_replica_timeout, + env->cfg->redis_replica_connect_timeout); + + moddata->logical_db = env->cfg->redis_logical_db; + moddata->replica_logical_db = env->cfg->redis_replica_logical_db; + + moddata->ctxs = calloc(env->cfg->num_threads, sizeof(redisContext*)); + if(!moddata->ctxs) { + log_err("out of memory"); + goto fail; } - if(env->cfg->redis_connect_timeout != 0) { - moddata->connect_timeout.tv_sec = - env->cfg->redis_connect_timeout / 1000; - moddata->connect_timeout.tv_usec = - (env->cfg->redis_connect_timeout % 1000) * 1000; + if((moddata->replica_server_host && moddata->replica_server_host[0]!=0) + || (moddata->replica_server_path && moddata->replica_server_path[0]!=0)) { + /* There is a replica configured, allocate ctxs */ + moddata->replica_ctxs = calloc(env->cfg->num_threads, sizeof(redisContext*)); + if(!moddata->replica_ctxs) { + log_err("out of memory"); + goto fail; + } } - moddata->logical_db = env->cfg->redis_logical_db; for(i = 0; i < moddata->numctxs; i++) { - redisContext* ctx = redis_connect(moddata); + redisContext* ctx = redis_connect( + moddata->server_host, + moddata->server_port, + moddata->server_path, + moddata->server_password, + moddata->logical_db, + moddata->connect_timeout, + moddata->command_timeout); if(!ctx) { - log_err("redis_init: failed to init redis"); - goto fail; + log_err("redis_init: failed to init redis " + "(for thread %d)", i); + /* And continue, the context can be established + * later, just like after a disconnect. */ } moddata->ctxs[i] = ctx; } + if(moddata->replica_ctxs) { + for(i = 0; i < moddata->numctxs; i++) { + redisContext* ctx = redis_connect( + moddata->replica_server_host, + moddata->replica_server_port, + moddata->replica_server_path, + moddata->replica_server_password, + moddata->replica_logical_db, + moddata->replica_connect_timeout, + moddata->replica_command_timeout); + if(!ctx) { + log_err("redis_init: failed to init redis " + "replica (for thread %d)", i); + /* And continue, the context can be established + * later, just like after a disconnect. */ + } + moddata->replica_ctxs[i] = ctx; + } + } cachedb_env->backend_data = moddata; - if(env->cfg->redis_expire_records) { + if(env->cfg->redis_expire_records && + moddata->ctxs[env->alloc->thread_num] != NULL) { redisReply* rep = NULL; int redis_reply_type = 0; - /** check if setex command is supported */ + /** check if set with ex command is supported */ rep = redis_command(env, cachedb_env, - "SETEX __UNBOUND_REDIS_CHECK__ 1 none", NULL, 0); + "SET __UNBOUND_REDIS_CHECK__ none EX 1", NULL, 0, 1); if(!rep) { /** init failed, no response from redis server*/ - log_err("redis_init: failed to init redis, the " - "redis-expire-records option requires the SETEX command " - "(redis >= 2.0.0)"); - goto fail; + goto set_with_ex_fail; } redis_reply_type = rep->type; freeReplyObject(rep); @@ -207,15 +291,18 @@ redis_init(struct module_env* env, struct cachedb_env* cachedb_env) case REDIS_REPLY_STATUS: break; default: - /** init failed, setex command not supported */ - log_err("redis_init: failed to init redis, the " - "redis-expire-records option requires the SETEX command " - "(redis >= 2.0.0)"); - goto fail; + /** init failed, set_with_ex command not supported */ + goto set_with_ex_fail; } + moddata->set_with_ex_available = 1; } return 1; +set_with_ex_fail: + log_err("redis_init: failure during redis_init, the " + "redis-expire-records option requires the SET with EX command " + "(redis >= 2.6.2)"); + return 1; fail: moddata_clean(&moddata); return 0; @@ -246,9 +333,9 @@ redis_deinit(struct module_env* env, struct cachedb_env* cachedb_env) */ static redisReply* redis_command(struct module_env* env, struct cachedb_env* cachedb_env, - const char* command, const uint8_t* data, size_t data_len) + const char* command, const uint8_t* data, size_t data_len, int write) { - redisContext* ctx; + redisContext* ctx, **ctx_selector; redisReply* rep; struct redis_moddata* d = (struct redis_moddata*) cachedb_env->backend_data; @@ -259,17 +346,38 @@ redis_command(struct module_env* env, struct cachedb_env* cachedb_env, * assumption throughout the unbound architecture, so we simply assert * it. */ log_assert(env->alloc->thread_num < d->numctxs); - ctx = d->ctxs[env->alloc->thread_num]; + + ctx_selector = !write && d->replica_ctxs + ?d->replica_ctxs + :d->ctxs; + ctx = ctx_selector[env->alloc->thread_num]; /* If we've not established a connection to the server or we've closed * it on a failure, try to re-establish a new one. Failures will be * logged in redis_connect(). */ if(!ctx) { - ctx = redis_connect(d); - d->ctxs[env->alloc->thread_num] = ctx; + if(!write && d->replica_ctxs) { + ctx = redis_connect( + d->replica_server_host, + d->replica_server_port, + d->replica_server_path, + d->replica_server_password, + d->replica_logical_db, + d->replica_connect_timeout, + d->replica_command_timeout); + } else { + ctx = redis_connect( + d->server_host, + d->server_port, + d->server_path, + d->server_password, + d->logical_db, + d->connect_timeout, + d->command_timeout); + } + ctx_selector[env->alloc->thread_num] = ctx; } - if(!ctx) - return NULL; + if(!ctx) return NULL; /* Send the command and get a reply, synchronously. */ rep = (redisReply*)redisCommand(ctx, command, data, data_len); @@ -279,7 +387,7 @@ redis_command(struct module_env* env, struct cachedb_env* cachedb_env, log_err("redis_command: failed to receive a reply, " "closing connection: %s", ctx->errstr); redisFree(ctx); - d->ctxs[env->alloc->thread_num] = NULL; + ctx_selector[env->alloc->thread_num] = NULL; return NULL; } @@ -309,7 +417,7 @@ redis_lookup(struct module_env* env, struct cachedb_env* cachedb_env, return 0; } - rep = redis_command(env, cachedb_env, cmdbuf, NULL, 0); + rep = redis_command(env, cachedb_env, cmdbuf, NULL, 0, 0); if(!rep) return 0; switch(rep->type) { @@ -346,11 +454,16 @@ redis_store(struct module_env* env, struct cachedb_env* cachedb_env, { redisReply* rep; int n; - int set_ttl = (env->cfg->redis_expire_records && + struct redis_moddata* moddata = (struct redis_moddata*) + cachedb_env->backend_data; + int set_ttl = (moddata->set_with_ex_available && + env->cfg->redis_expire_records && (!env->cfg->serve_expired || env->cfg->serve_expired_ttl > 0)); /* Supported commands: * - "SET " + key + " %b" - * - "SETEX " + key + " " + ttl + " %b" + * - "SET " + key + " %b EX " + ttl + * older redis 2.0.0 was "SETEX " + key + " " + ttl + " %b" + * - "EXPIRE " + key + " 0" */ char cmdbuf[6+(CACHEDB_HASHSIZE/8)*2+11+3+1]; @@ -358,14 +471,22 @@ redis_store(struct module_env* env, struct cachedb_env* cachedb_env, verbose(VERB_ALGO, "redis_store %s (%d bytes)", key, (int)data_len); /* build command to set to a binary safe string */ n = snprintf(cmdbuf, sizeof(cmdbuf), "SET %s %%b", key); + } else if(ttl == 0) { + /* use the EXPIRE command, SET with EX 0 is an invalid time. */ + /* Replies with REDIS_REPLY_INTEGER of 1. */ + verbose(VERB_ALGO, "redis_store expire %s (%d bytes)", + key, (int)data_len); + n = snprintf(cmdbuf, sizeof(cmdbuf), "EXPIRE %s 0", key); + data = NULL; + data_len = 0; } else { /* add expired ttl time to redis ttl to avoid premature eviction of key */ ttl += env->cfg->serve_expired_ttl; verbose(VERB_ALGO, "redis_store %s (%d bytes) with ttl %u", - key, (int)data_len, (uint32_t)ttl); + key, (int)data_len, (unsigned)(uint32_t)ttl); /* build command to set to a binary safe string */ - n = snprintf(cmdbuf, sizeof(cmdbuf), "SETEX %s %u %%b", key, - (uint32_t)ttl); + n = snprintf(cmdbuf, sizeof(cmdbuf), "SET %s %%b EX %u", key, + (unsigned)(uint32_t)ttl); } @@ -374,11 +495,12 @@ redis_store(struct module_env* env, struct cachedb_env* cachedb_env, return; } - rep = redis_command(env, cachedb_env, cmdbuf, data, data_len); + rep = redis_command(env, cachedb_env, cmdbuf, data, data_len, 1); if(rep) { verbose(VERB_ALGO, "redis_store set completed"); if(rep->type != REDIS_REPLY_STATUS && - rep->type != REDIS_REPLY_ERROR) { + rep->type != REDIS_REPLY_ERROR && + rep->type != REDIS_REPLY_INTEGER) { log_err("redis_store: unexpected type of reply (%d)", rep->type); } diff --git a/compat/malloc.c b/compat/malloc.c index d8097b13e024..74beae01c98c 100644 --- a/compat/malloc.c +++ b/compat/malloc.c @@ -5,12 +5,8 @@ #undef malloc #include <sys/types.h> -#ifndef USE_WINSOCK -void *malloc (); -#else /* provide a prototype */ void *malloc (size_t n); -#endif /* Allocate an N-byte block of memory from the heap. If N is zero, allocate a 1-byte block. */ diff --git a/config.h.in b/config.h.in index dc03e82dddba..f2dc8c8b92b3 100644 --- a/config.h.in +++ b/config.h.in @@ -378,6 +378,9 @@ /* Define if we have LibreSSL */ #undef HAVE_LIBRESSL +/* If we have atomic_store */ +#undef HAVE_LINK_ATOMIC_STORE + /* Define to 1 if you have the <linux/net_tstamp.h> header file. */ #undef HAVE_LINUX_NET_TSTAMP_H @@ -663,6 +666,9 @@ /* Define to 1 if you have the <stdarg.h> header file. */ #undef HAVE_STDARG_H +/* Define to 1 if you have the <stdatomic.h> header file. */ +#undef HAVE_STDATOMIC_H + /* Define to 1 if you have the <stdbool.h> header file. */ #undef HAVE_STDBOOL_H diff --git a/configure b/configure index 918a0632013d..0b78d97b16e9 100755 --- a/configure +++ b/configure @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for unbound 1.22.0. +# Generated by GNU Autoconf 2.71 for unbound 1.23.0. # # Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>. # @@ -622,8 +622,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='unbound' PACKAGE_TARNAME='unbound' -PACKAGE_VERSION='1.22.0' -PACKAGE_STRING='unbound 1.22.0' +PACKAGE_VERSION='1.23.0' +PACKAGE_STRING='unbound 1.23.0' PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues' PACKAGE_URL='' @@ -712,6 +712,7 @@ SSLLIB HAVE_SSL PC_CRYPTO_DEPENDENCY CONFIG_DATE +SOURCE_DATE_EPOCH GCC_DOCKER_LINTFLAGS NETBSD_LINTFLAGS PYUNBOUND_UNINSTALL @@ -959,6 +960,7 @@ SYSTEMD_LIBS SYSTEMD_DAEMON_CFLAGS SYSTEMD_DAEMON_LIBS PYTHON_VERSION +SOURCE_DATE_EPOCH PROTOBUFC_CFLAGS PROTOBUFC_LIBS' @@ -1509,7 +1511,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures unbound 1.22.0 to adapt to many kinds of systems. +\`configure' configures unbound 1.23.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1575,7 +1577,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of unbound 1.22.0:";; + short | recursive ) echo "Configuration of unbound 1.23.0:";; esac cat <<\_ACEOF @@ -1752,6 +1754,10 @@ Some influential environment variables: The installed Python version to use, for example '2.3'. This string will be appended to the Python interpreter canonical name. + SOURCE_DATE_EPOCH + If it is set, it uses the value of that variable instead of the + current time as the build timestamp. The format is a unix + timestamp. This enables reproducible build output. PROTOBUFC_CFLAGS C compiler flags for PROTOBUFC, overriding pkg-config PROTOBUFC_LIBS @@ -1824,7 +1830,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -unbound configure 1.22.0 +unbound configure 1.23.0 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2481,7 +2487,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by unbound $as_me 1.22.0, which was +It was created by unbound $as_me 1.23.0, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3243,13 +3249,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu UNBOUND_VERSION_MAJOR=1 -UNBOUND_VERSION_MINOR=22 +UNBOUND_VERSION_MINOR=23 UNBOUND_VERSION_MICRO=0 LIBUNBOUND_CURRENT=9 -LIBUNBOUND_REVISION=30 +LIBUNBOUND_REVISION=31 LIBUNBOUND_AGE=1 # 1.0.0 had 0:12:0 # 1.0.1 had 0:13:0 @@ -3347,6 +3353,7 @@ LIBUNBOUND_AGE=1 # 1.21.0 had 9:28:1 # 1.21.1 had 9:29:1 # 1.22.0 had 9:30:1 +# 1.23.0 had 9:31:1 # Current -- the number of the binary API that we're implementing # Revision -- which iteration of the implementation of the binary @@ -16093,6 +16100,14 @@ then : fi +ac_fn_c_check_header_compile "$LINENO" "stdatomic.h" "ac_cv_header_stdatomic_h" "$ac_includes_default +" +if test "x$ac_cv_header_stdatomic_h" = xyes +then : + printf "%s\n" "#define HAVE_STDATOMIC_H 1" >>confdefs.h + +fi + # check for types. # Using own tests for int64* because autoconf builtin only give 32bit. @@ -19893,7 +19908,26 @@ if test "`uname`" = "Linux"; then GCC_DOCKER_LINTFLAGS='-syntax' fi -CONFIG_DATE=`date +%Y%m%d` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build time" >&5 +printf %s "checking for build time... " >&6; } +ax_date_fmt="%Y%m%d" +if test x"$SOURCE_DATE_EPOCH" = x +then : + CONFIG_DATE=`date "+$ax_date_fmt"` +else $as_nop + ax_build_date=`date -u -d "@$SOURCE_DATE_EPOCH" "+$ax_date_fmt" 2>/dev/null \ + || date -u -r "$SOURCE_DATE_EPOCH" "+$ax_date_fmt" 2>/dev/null` + if test x"$ax_build_date" = x +then : + as_fn_error $? "malformed SOURCE_DATE_EPOCH" "$LINENO" 5 +else $as_nop + CONFIG_DATE=$ax_build_date +fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CONFIG_DATE" >&5 +printf "%s\n" "$CONFIG_DATE" >&6; } + + # Checks for libraries. @@ -23496,6 +23530,48 @@ if echo $host_os | grep darwin8 > /dev/null; then printf "%s\n" "#define DARWIN_BROKEN_SETREUID 1" >>confdefs.h fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for atomic_store" >&5 +printf %s "checking for atomic_store... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +#ifdef HAVE_STDATOMIC_H +#include <stdatomic.h> +#endif + +int +main (void) +{ + + int newvar = 5, var = 0; + atomic_store((_Atomic int*)&var, newvar); + newvar = 0; + /* condition to use the variables. */ + if(var == newvar) return 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define HAVE_LINK_ATOMIC_STORE 1" >>confdefs.h + + +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ac_fn_check_decl "$LINENO" "inet_pton" "ac_cv_have_decl_inet_pton" " $ac_includes_default #ifdef HAVE_NETINET_IN_H @@ -24997,9 +25073,27 @@ printf "%s\n" "#define MAXSYSLOGMSGLEN 10240" >>confdefs.h -version=1.22.0 +version=1.23.0 + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build time" >&5 +printf %s "checking for build time... " >&6; } +ax_date_fmt="%b %e, %Y" +if test x"$SOURCE_DATE_EPOCH" = x +then : + date=`date "+$ax_date_fmt"` +else $as_nop + ax_build_date=`date -u -d "@$SOURCE_DATE_EPOCH" "+$ax_date_fmt" 2>/dev/null \ + || date -u -r "$SOURCE_DATE_EPOCH" "+$ax_date_fmt" 2>/dev/null` + if test x"$ax_build_date" = x +then : + as_fn_error $? "malformed SOURCE_DATE_EPOCH" "$LINENO" 5 +else $as_nop + date=$ax_build_date +fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $date" >&5 +printf "%s\n" "$date" >&6; } -date=`date +'%b %e, %Y'` ac_config_files="$ac_config_files Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service contrib/unbound_portable.service" @@ -25509,7 +25603,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by unbound $as_me 1.22.0, which was +This file was extended by unbound $as_me 1.23.0, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -25577,7 +25671,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -unbound config.status 1.22.0 +unbound config.status 1.23.0 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/configure.ac b/configure.ac index 3f5759f5873c..76239c099572 100644 --- a/configure.ac +++ b/configure.ac @@ -2,6 +2,7 @@ # Process this file with autoconf to produce a configure script. AC_PREREQ([2.56]) sinclude(acx_nlnetlabs.m4) +sinclude(ax_build_date_epoch.m4) sinclude(ax_pthread.m4) sinclude(acx_python.m4) sinclude(ax_pkg_swig.m4) @@ -10,7 +11,7 @@ sinclude(dnscrypt/dnscrypt.m4) # must be numbers. ac_defun because of later processing m4_define([VERSION_MAJOR],[1]) -m4_define([VERSION_MINOR],[22]) +m4_define([VERSION_MINOR],[23]) m4_define([VERSION_MICRO],[0]) AC_INIT([unbound],m4_defn([VERSION_MAJOR]).m4_defn([VERSION_MINOR]).m4_defn([VERSION_MICRO]),[unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues],[unbound]) AC_SUBST(UNBOUND_VERSION_MAJOR, [VERSION_MAJOR]) @@ -18,7 +19,7 @@ AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR]) AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO]) LIBUNBOUND_CURRENT=9 -LIBUNBOUND_REVISION=30 +LIBUNBOUND_REVISION=31 LIBUNBOUND_AGE=1 # 1.0.0 had 0:12:0 # 1.0.1 had 0:13:0 @@ -116,6 +117,7 @@ LIBUNBOUND_AGE=1 # 1.21.0 had 9:28:1 # 1.21.1 had 9:29:1 # 1.22.0 had 9:30:1 +# 1.23.0 had 9:31:1 # Current -- the number of the binary API that we're implementing # Revision -- which iteration of the implementation of the binary @@ -522,6 +524,7 @@ AC_CHECK_HEADERS([netioapi.h],,, [AC_INCLUDES_DEFAULT # Check for Linux timestamping headers AC_CHECK_HEADERS([linux/net_tstamp.h],,, [AC_INCLUDES_DEFAULT]) +AC_CHECK_HEADERS([stdatomic.h],,, [AC_INCLUDES_DEFAULT]) # check for types. # Using own tests for int64* because autoconf builtin only give 32bit. @@ -907,7 +910,8 @@ if test "`uname`" = "Linux"; then GCC_DOCKER_LINTFLAGS='-syntax' AC_SUBST(GCC_DOCKER_LINTFLAGS) fi -CONFIG_DATE=`date +%Y%m%d` +AX_BUILD_DATE_EPOCH(CONFIG_DATE, [%Y%m%d]) +AC_ARG_VAR(SOURCE_DATE_EPOCH, [If it is set, it uses the value of that variable instead of the current time as the build timestamp. The format is a unix timestamp. This enables reproducible build output.]) AC_SUBST(CONFIG_DATE) # Checks for libraries. @@ -1814,6 +1818,25 @@ AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])]) if echo $host_os | grep darwin8 > /dev/null; then AC_DEFINE(DARWIN_BROKEN_SETREUID, 1, [Define this if on macOSX10.4-darwin8 and setreuid and setregid do not work]) fi + +AC_MSG_CHECKING([for atomic_store]) +AC_LINK_IFELSE([AC_LANG_PROGRAM(AC_INCLUDES_DEFAULT [[ +#ifdef HAVE_STDATOMIC_H +#include <stdatomic.h> +#endif +]], [[ + int newvar = 5, var = 0; + atomic_store((_Atomic int*)&var, newvar); + newvar = 0; + /* condition to use the variables. */ + if(var == newvar) return 1; +]])], [ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_LINK_ATOMIC_STORE, 1, [If we have atomic_store]) +], [ + AC_MSG_RESULT([no]) +]) + AC_CHECK_DECLS([inet_pton,inet_ntop], [], [], [ AC_INCLUDES_DEFAULT #ifdef HAVE_NETINET_IN_H @@ -2434,7 +2457,8 @@ char *unbound_stat_strdup_log(const char *s, const char* file, int line, dnl if we build from source tree, the man pages need @date@ and @version@ dnl if this is a distro tarball, that was already done by makedist.sh AC_SUBST(version, [VERSION_MAJOR.VERSION_MINOR.VERSION_MICRO]) -AC_SUBST(date, [`date +'%b %e, %Y'`]) +AX_BUILD_DATE_EPOCH(date, [[%b %e, %Y]]) +AC_SUBST(date) AC_CONFIG_FILES([Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service contrib/unbound_portable.service]) AC_CONFIG_HEADERS([config.h]) diff --git a/configure~ b/configure~ index 918a0632013d..0b78d97b16e9 100755 --- a/configure~ +++ b/configure~ @@ -1,6 +1,6 @@ #! /bin/sh # Guess values for system-dependent variables and create Makefiles. -# Generated by GNU Autoconf 2.71 for unbound 1.22.0. +# Generated by GNU Autoconf 2.71 for unbound 1.23.0. # # Report bugs to <unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues>. # @@ -622,8 +622,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='unbound' PACKAGE_TARNAME='unbound' -PACKAGE_VERSION='1.22.0' -PACKAGE_STRING='unbound 1.22.0' +PACKAGE_VERSION='1.23.0' +PACKAGE_STRING='unbound 1.23.0' PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues' PACKAGE_URL='' @@ -712,6 +712,7 @@ SSLLIB HAVE_SSL PC_CRYPTO_DEPENDENCY CONFIG_DATE +SOURCE_DATE_EPOCH GCC_DOCKER_LINTFLAGS NETBSD_LINTFLAGS PYUNBOUND_UNINSTALL @@ -959,6 +960,7 @@ SYSTEMD_LIBS SYSTEMD_DAEMON_CFLAGS SYSTEMD_DAEMON_LIBS PYTHON_VERSION +SOURCE_DATE_EPOCH PROTOBUFC_CFLAGS PROTOBUFC_LIBS' @@ -1509,7 +1511,7 @@ if test "$ac_init_help" = "long"; then # Omit some internal or obsolete options to make the list less imposing. # This message is too long to be a string in the A/UX 3.1 sh. cat <<_ACEOF -\`configure' configures unbound 1.22.0 to adapt to many kinds of systems. +\`configure' configures unbound 1.23.0 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1575,7 +1577,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of unbound 1.22.0:";; + short | recursive ) echo "Configuration of unbound 1.23.0:";; esac cat <<\_ACEOF @@ -1752,6 +1754,10 @@ Some influential environment variables: The installed Python version to use, for example '2.3'. This string will be appended to the Python interpreter canonical name. + SOURCE_DATE_EPOCH + If it is set, it uses the value of that variable instead of the + current time as the build timestamp. The format is a unix + timestamp. This enables reproducible build output. PROTOBUFC_CFLAGS C compiler flags for PROTOBUFC, overriding pkg-config PROTOBUFC_LIBS @@ -1824,7 +1830,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -unbound configure 1.22.0 +unbound configure 1.23.0 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2481,7 +2487,7 @@ cat >config.log <<_ACEOF This file contains any messages produced by compilers while running configure, to aid debugging if configure makes a mistake. -It was created by unbound $as_me 1.22.0, which was +It was created by unbound $as_me 1.23.0, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3243,13 +3249,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu UNBOUND_VERSION_MAJOR=1 -UNBOUND_VERSION_MINOR=22 +UNBOUND_VERSION_MINOR=23 UNBOUND_VERSION_MICRO=0 LIBUNBOUND_CURRENT=9 -LIBUNBOUND_REVISION=30 +LIBUNBOUND_REVISION=31 LIBUNBOUND_AGE=1 # 1.0.0 had 0:12:0 # 1.0.1 had 0:13:0 @@ -3347,6 +3353,7 @@ LIBUNBOUND_AGE=1 # 1.21.0 had 9:28:1 # 1.21.1 had 9:29:1 # 1.22.0 had 9:30:1 +# 1.23.0 had 9:31:1 # Current -- the number of the binary API that we're implementing # Revision -- which iteration of the implementation of the binary @@ -16093,6 +16100,14 @@ then : fi +ac_fn_c_check_header_compile "$LINENO" "stdatomic.h" "ac_cv_header_stdatomic_h" "$ac_includes_default +" +if test "x$ac_cv_header_stdatomic_h" = xyes +then : + printf "%s\n" "#define HAVE_STDATOMIC_H 1" >>confdefs.h + +fi + # check for types. # Using own tests for int64* because autoconf builtin only give 32bit. @@ -19893,7 +19908,26 @@ if test "`uname`" = "Linux"; then GCC_DOCKER_LINTFLAGS='-syntax' fi -CONFIG_DATE=`date +%Y%m%d` +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build time" >&5 +printf %s "checking for build time... " >&6; } +ax_date_fmt="%Y%m%d" +if test x"$SOURCE_DATE_EPOCH" = x +then : + CONFIG_DATE=`date "+$ax_date_fmt"` +else $as_nop + ax_build_date=`date -u -d "@$SOURCE_DATE_EPOCH" "+$ax_date_fmt" 2>/dev/null \ + || date -u -r "$SOURCE_DATE_EPOCH" "+$ax_date_fmt" 2>/dev/null` + if test x"$ax_build_date" = x +then : + as_fn_error $? "malformed SOURCE_DATE_EPOCH" "$LINENO" 5 +else $as_nop + CONFIG_DATE=$ax_build_date +fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $CONFIG_DATE" >&5 +printf "%s\n" "$CONFIG_DATE" >&6; } + + # Checks for libraries. @@ -23496,6 +23530,48 @@ if echo $host_os | grep darwin8 > /dev/null; then printf "%s\n" "#define DARWIN_BROKEN_SETREUID 1" >>confdefs.h fi + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for atomic_store" >&5 +printf %s "checking for atomic_store... " >&6; } +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +#ifdef HAVE_STDATOMIC_H +#include <stdatomic.h> +#endif + +int +main (void) +{ + + int newvar = 5, var = 0; + atomic_store((_Atomic int*)&var, newvar); + newvar = 0; + /* condition to use the variables. */ + if(var == newvar) return 1; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define HAVE_LINK_ATOMIC_STORE 1" >>confdefs.h + + +else $as_nop + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + ac_fn_check_decl "$LINENO" "inet_pton" "ac_cv_have_decl_inet_pton" " $ac_includes_default #ifdef HAVE_NETINET_IN_H @@ -24997,9 +25073,27 @@ printf "%s\n" "#define MAXSYSLOGMSGLEN 10240" >>confdefs.h -version=1.22.0 +version=1.23.0 + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build time" >&5 +printf %s "checking for build time... " >&6; } +ax_date_fmt="%b %e, %Y" +if test x"$SOURCE_DATE_EPOCH" = x +then : + date=`date "+$ax_date_fmt"` +else $as_nop + ax_build_date=`date -u -d "@$SOURCE_DATE_EPOCH" "+$ax_date_fmt" 2>/dev/null \ + || date -u -r "$SOURCE_DATE_EPOCH" "+$ax_date_fmt" 2>/dev/null` + if test x"$ax_build_date" = x +then : + as_fn_error $? "malformed SOURCE_DATE_EPOCH" "$LINENO" 5 +else $as_nop + date=$ax_build_date +fi +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $date" >&5 +printf "%s\n" "$date" >&6; } -date=`date +'%b %e, %Y'` ac_config_files="$ac_config_files Makefile doc/example.conf doc/libunbound.3 doc/unbound.8 doc/unbound-anchor.8 doc/unbound-checkconf.8 doc/unbound.conf.5 doc/unbound-control.8 doc/unbound-host.1 smallapp/unbound-control-setup.sh dnstap/dnstap_config.h dnscrypt/dnscrypt_config.h contrib/libunbound.pc contrib/unbound.socket contrib/unbound.service contrib/unbound_portable.service" @@ -25509,7 +25603,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_write_fail=1 # report actual input values of CONFIG_FILES etc. instead of their # values after options handling. ac_log=" -This file was extended by unbound $as_me 1.22.0, which was +This file was extended by unbound $as_me 1.23.0, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -25577,7 +25671,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac_cs_config" | sed "s/^ //; s/'/'\\\\\\\\ cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -unbound config.status 1.22.0 +unbound config.status 1.23.0 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" diff --git a/contrib/android/install_expat.sh b/contrib/android/install_expat.sh index ffb22322c803..5d736b8b96f1 100755 --- a/contrib/android/install_expat.sh +++ b/contrib/android/install_expat.sh @@ -1,21 +1,24 @@ #!/usr/bin/env bash +LIBEXPAT_FNAME=expat-2.7.0 +LIBEXPAT_VERSION_DIR=R_2_7_0 + echo "Downloading Expat" -if ! curl -L -k -s -o expat-2.2.9.tar.gz https://github.com/libexpat/libexpat/releases/download/R_2_2_9/expat-2.2.9.tar.gz; +if ! curl -L -k -s -o $LIBEXPAT_FNAME.tar.gz https://github.com/libexpat/libexpat/releases/download/$LIBEXPAT_VERSION_DIR/$LIBEXPAT_FNAME.tar.gz; then echo "Failed to download Expat" exit 1 fi echo "Unpacking Expat" -rm -rf ./expat-2.2.9 -if ! tar -xf expat-2.2.9.tar.gz; +rm -rf ./$LIBEXPAT_FNAME +if ! tar -xf $LIBEXPAT_FNAME.tar.gz; then echo "Failed to unpack Expat" exit 1 fi -cd expat-2.2.9 || exit 1 +cd $LIBEXPAT_FNAME || exit 1 echo "Configuring Expat" if ! ./configure --build="$AUTOTOOLS_BUILD" --host="$AUTOTOOLS_HOST" --prefix="$ANDROID_PREFIX"; then diff --git a/contrib/ios/install_expat.sh b/contrib/ios/install_expat.sh index 9471b5aff2dd..4972c467b549 100755 --- a/contrib/ios/install_expat.sh +++ b/contrib/ios/install_expat.sh @@ -1,28 +1,32 @@ #!/usr/bin/env bash +LIBEXPAT_FNAME=expat-2.7.0 +LIBEXPAT_VERSION_DIR=R_2_7_0 + echo "Downloading Expat" -if ! curl -L -k -s -o expat-2.2.9.tar.gz https://github.com/libexpat/libexpat/releases/download/R_2_2_9/expat-2.2.9.tar.gz; +if ! curl -L -k -s -o $LIBEXPAT_FNAME.tar.gz https://github.com/libexpat/libexpat/releases/download/$LIBEXPAT_VERSION_DIR/$LIBEXPAT_FNAME.tar.gz; then echo "Failed to download Expat" exit 1 fi echo "Unpacking Expat" -rm -rf ./expat-2.2.9 -if ! tar -xf expat-2.2.9.tar.gz; +rm -rf ./$LIBEXPAT_FNAME +if ! tar -xf $LIBEXPAT_FNAME.tar.gz; then echo "Failed to unpack Expat" exit 1 fi -cd expat-2.2.9 || exit 1 +cd $LIBEXPAT_FNAME || exit 1 export PKG_CONFIG_PATH="$IOS_PREFIX/lib/pkgconfig" echo "Configuring Expat" -if ! ./configure \ - --build="$AUTOTOOLS_BUILD" --host="$AUTOTOOLS_HOST" \ - --prefix="$IOS_PREFIX" ; then +if ! ./configure --without-tests \ + --build="$AUTOTOOLS_BUILD" --host="$AUTOTOOLS_HOST" \ + --prefix="$IOS_PREFIX" ; +then echo "Error: Failed to configure Expat" cat config.log exit 1 diff --git a/daemon/acl_list.c b/daemon/acl_list.c index 83cfd7ddf939..24cd9b399142 100644 --- a/daemon/acl_list.c +++ b/daemon/acl_list.c @@ -221,7 +221,9 @@ acl_interface_insert(struct acl_list* acl_interface, struct sockaddr_storage* addr, socklen_t addrlen, enum acl_access control) { - return acl_find_or_create(acl_interface, addr, addrlen, control); + struct acl_addr* node = acl_find_or_create(acl_interface, addr, addrlen, control); + node->is_interface = 1; + return node; } /** apply acl_tag string */ @@ -551,17 +553,6 @@ acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg, return 1; } -int -acl_interface_compare(const void* k1, const void* k2) -{ - struct addr_tree_node* n1 = (struct addr_tree_node*)k1; - struct addr_tree_node* n2 = (struct addr_tree_node*)k2; - return sockaddr_cmp(&n1->addr, n1->addrlen, &n2->addr, - n2->addrlen); - /* We don't care about comparing node->net. All addresses in the - * acl_interface tree have either 32 (ipv4) or 128 (ipv6). */ -} - void acl_interface_init(struct acl_list* acl_interface) { @@ -816,10 +807,23 @@ log_acl_action(const char* action, struct sockaddr_storage* addr, addr_to_str(&acladdr->node.addr, acladdr->node.addrlen, n, sizeof(n)); verbose(VERB_ALGO, "%s query from %s port %d because of " - "%s/%d %s", action, a, (int)port, n, acladdr->node.net, + "%s/%d %s%s", action, a, (int)port, n, + acladdr->node.net, + acladdr->is_interface?"(ACL on interface IP) ":"", acl_access_to_str(acl)); } else { verbose(VERB_ALGO, "%s query from %s port %d", action, a, (int)port); } } + +void acl_list_swap_tree(struct acl_list* acl, struct acl_list* data) +{ + /* swap tree and region */ + rbtree_type oldtree = acl->tree; + struct regional* oldregion = acl->region; + acl->tree = data->tree; + acl->region = data->region; + data->tree = oldtree; + data->region = oldregion; +} diff --git a/daemon/acl_list.h b/daemon/acl_list.h index 9da43bef37e5..416169ee924b 100644 --- a/daemon/acl_list.h +++ b/daemon/acl_list.h @@ -107,6 +107,8 @@ struct acl_addr { struct config_strlist** tag_datas; /** size of the tag_datas array */ size_t tag_datas_size; + /* If the acl node is for an interface */ + int is_interface; /* view element, NULL if none */ struct view* view; }; @@ -147,9 +149,6 @@ acl_interface_insert(struct acl_list* acl_interface, int acl_list_apply_cfg(struct acl_list* acl, struct config_file* cfg, struct views* v); -/** compare ACL interface "addr_tree" nodes (+port) */ -int acl_interface_compare(const void* k1, const void* k2); - /** * Initialise (also clean) the acl_interface struct. * @param acl_interface: where to store. @@ -202,4 +201,12 @@ const char* acl_access_to_str(enum acl_access acl); void log_acl_action(const char* action, struct sockaddr_storage* addr, socklen_t addrlen, enum acl_access acl, struct acl_addr* acladdr); +/** + * Swap internal tree with preallocated entries. + * @param acl: the acl structure. + * @param data: the data structure used to take elements from. This contains + * the old elements on return. + */ +void acl_list_swap_tree(struct acl_list* acl, struct acl_list* data); + #endif /* DAEMON_ACL_LIST_H */ diff --git a/daemon/cachedump.c b/daemon/cachedump.c index c4f55d8c9cbb..ba986c763edc 100644 --- a/daemon/cachedump.c +++ b/daemon/cachedump.c @@ -692,7 +692,7 @@ load_msg(RES* ssl, sldns_buffer* buf, struct worker* worker) return 1; /* skip this one, not all references satisfied */ if(!dns_cache_store(&worker->env, &qinf, &rep, 0, 0, 0, NULL, flags, - *worker->env.now)) { + *worker->env.now, 1)) { log_warn("error out of memory"); return 0; } @@ -836,7 +836,7 @@ int print_deleg_lookup(RES* ssl, struct worker* worker, uint8_t* nm, struct delegpt* dp; struct dns_msg* msg; struct regional* region = worker->scratchpad; - char b[260]; + char b[LDNS_MAX_DOMAINLEN]; struct query_info qinfo; struct iter_hints_stub* stub; int nolock = 0; diff --git a/daemon/daemon.c b/daemon/daemon.c index 1c8272b14e81..f882bb9ad62e 100644 --- a/daemon/daemon.c +++ b/daemon/daemon.c @@ -323,8 +323,7 @@ daemon_init(void) return daemon; } -static int setup_acl_for_ports(struct acl_list* list, - struct listen_port* port_list) +int setup_acl_for_ports(struct acl_list* list, struct listen_port* port_list) { struct acl_addr* acl_node; for(; port_list; port_list=port_list->next) { @@ -717,16 +716,16 @@ daemon_fork(struct daemon* daemon) #endif log_assert(daemon); - if(!(daemon->views = views_create())) + if(!(daemon->env->views = views_create())) fatal_exit("Could not create views: out of memory"); /* create individual views and their localzone/data trees */ - if(!views_apply_cfg(daemon->views, daemon->cfg)) + if(!views_apply_cfg(daemon->env->views, daemon->cfg)) fatal_exit("Could not set up views"); - if(!acl_list_apply_cfg(daemon->acl, daemon->cfg, daemon->views)) + if(!acl_list_apply_cfg(daemon->acl, daemon->cfg, daemon->env->views)) fatal_exit("Could not setup access control list"); if(!acl_interface_apply_cfg(daemon->acl_interface, daemon->cfg, - daemon->views)) + daemon->env->views)) fatal_exit("Could not setup interface control list"); if(!tcl_list_apply_cfg(daemon->tcl, daemon->cfg)) fatal_exit("Could not setup TCP connection limits"); @@ -762,15 +761,15 @@ daemon_fork(struct daemon* daemon) fatal_exit("Could not set root or stub hints"); /* process raw response-ip configuration data */ - if(!(daemon->respip_set = respip_set_create())) + if(!(daemon->env->respip_set = respip_set_create())) fatal_exit("Could not create response IP set"); - if(!respip_global_apply_cfg(daemon->respip_set, daemon->cfg)) + if(!respip_global_apply_cfg(daemon->env->respip_set, daemon->cfg)) fatal_exit("Could not set up response IP set"); - if(!respip_views_apply_cfg(daemon->views, daemon->cfg, + if(!respip_views_apply_cfg(daemon->env->views, daemon->cfg, &have_view_respip_cfg)) fatal_exit("Could not set up per-view response IP sets"); - daemon->use_response_ip = !respip_set_is_empty(daemon->respip_set) || - have_view_respip_cfg; + daemon->use_response_ip = !respip_set_is_empty( + daemon->env->respip_set) || have_view_respip_cfg; /* setup modules */ daemon_setup_modules(daemon); @@ -886,14 +885,18 @@ daemon_cleanup(struct daemon* daemon) daemon->env->hints = NULL; local_zones_delete(daemon->local_zones); daemon->local_zones = NULL; - respip_set_delete(daemon->respip_set); - daemon->respip_set = NULL; - views_delete(daemon->views); - daemon->views = NULL; + respip_set_delete(daemon->env->respip_set); + daemon->env->respip_set = NULL; + views_delete(daemon->env->views); + daemon->env->views = NULL; if(daemon->env->auth_zones) auth_zones_cleanup(daemon->env->auth_zones); /* key cache is cleared by module deinit during next daemon_fork() */ daemon_remote_clear(daemon->rc); + if(daemon->fast_reload_thread) + fast_reload_thread_stop(daemon->fast_reload_thread); + if(daemon->fast_reload_printq_list) + fast_reload_printq_list_delete(daemon->fast_reload_printq_list); for(i=0; i<daemon->num; i++) worker_delete(daemon->workers[i]); free(daemon->workers); @@ -951,11 +954,16 @@ daemon_delete(struct daemon* daemon) listen_desetup_locks(); free(daemon->chroot); free(daemon->pidfile); + free(daemon->cfgfile); free(daemon->env); #ifdef HAVE_SSL listen_sslctx_delete_ticket_keys(); - SSL_CTX_free((SSL_CTX*)daemon->listen_sslctx); - SSL_CTX_free((SSL_CTX*)daemon->connect_sslctx); + SSL_CTX_free((SSL_CTX*)daemon->listen_dot_sslctx); + SSL_CTX_free((SSL_CTX*)daemon->listen_doh_sslctx); + SSL_CTX_free((SSL_CTX*)daemon->connect_dot_sslctx); +#endif +#ifdef HAVE_NGTCP2 + SSL_CTX_free((SSL_CTX*)daemon->listen_quic_sslctx); #endif free(daemon); /* lex cleanup */ diff --git a/daemon/daemon.h b/daemon/daemon.h index fc1bde713cae..2295761ab7e3 100644 --- a/daemon/daemon.h +++ b/daemon/daemon.h @@ -60,6 +60,8 @@ struct respip_set; struct shm_main_info; struct doq_table; struct cookie_secrets; +struct fast_reload_thread; +struct fast_reload_printq; #include "dnstap/dnstap_config.h" #ifdef USE_DNSTAP @@ -97,8 +99,14 @@ struct daemon { struct listen_port* rc_ports; /** remote control connections management (for first worker) */ struct daemon_remote* rc; - /** ssl context for listening to dnstcp over ssl, and connecting ssl */ - void* listen_sslctx, *connect_sslctx; + /** ssl context for listening to dnstcp over ssl */ + void* listen_dot_sslctx; + /** ssl context for connecting to dnstcp over ssl */ + void* connect_dot_sslctx; + /** ssl context for listening to DoH */ + void* listen_doh_sslctx; + /** ssl context for listening to quic */ + void* listen_quic_sslctx; /** num threads allocated */ int num; /** num threads allocated in the previous config or 0 at first */ @@ -131,15 +139,11 @@ struct daemon { struct timeval time_last_stat; /** time when daemon started */ struct timeval time_boot; - /** views structure containing view tree */ - struct views* views; #ifdef USE_DNSTAP /** the dnstap environment master value, copied and changed by threads*/ struct dt_env* dtenv; #endif struct shm_main_info* shm_info; - /** response-ip set with associated actions and tags. */ - struct respip_set* respip_set; /** some response-ip tags or actions are configured if true */ int use_response_ip; /** some RPZ policies are configured */ @@ -154,6 +158,17 @@ struct daemon { int reuse_cache; /** the EDNS cookie secrets from the cookie-secret-file */ struct cookie_secrets* cookie_secrets; + /** the fast reload thread, or NULL */ + struct fast_reload_thread* fast_reload_thread; + /** the fast reload printq list */ + struct fast_reload_printq* fast_reload_printq_list; + /** the fast reload option to drop mesh queries, true if so. */ + int fast_reload_drop_mesh; + /** for fast reload, if the tcl, tcp connection limits, has + * changes for workers */ + int fast_reload_tcl_has_changes; + /** config file name */ + char* cfgfile; }; /** @@ -206,4 +221,12 @@ void daemon_delete(struct daemon* daemon); */ void daemon_apply_cfg(struct daemon* daemon, struct config_file* cfg); +/** + * Setup acl list to have entries for the port list. + * @param list: the acl interface + * @param port_list: list of open ports, or none. + * @return false on failure + */ +int setup_acl_for_ports(struct acl_list* list, struct listen_port* port_list); + #endif /* DAEMON_H */ diff --git a/daemon/remote.c b/daemon/remote.c index 8877cd19402b..89134efc92a8 100644 --- a/daemon/remote.c +++ b/daemon/remote.c @@ -52,6 +52,9 @@ #ifdef HAVE_OPENSSL_BN_H #include <openssl/bn.h> #endif +#ifdef HAVE_STDATOMIC_H +#include <stdatomic.h> +#endif #include <ctype.h> #include "daemon/remote.h" @@ -63,6 +66,7 @@ #include "util/config_file.h" #include "util/net_help.h" #include "util/module.h" +#include "util/ub_event.h" #include "services/listen_dnsport.h" #include "services/cache/rrset.h" #include "services/cache/infra.h" @@ -77,10 +81,14 @@ #include "validator/val_kcache.h" #include "validator/val_kentry.h" #include "validator/val_anchor.h" +#include "validator/val_neg.h" #include "iterator/iterator.h" #include "iterator/iter_fwd.h" #include "iterator/iter_hints.h" #include "iterator/iter_delegpt.h" +#include "iterator/iter_utils.h" +#include "iterator/iter_donotq.h" +#include "iterator/iter_priv.h" #include "services/outbound_list.h" #include "services/outside_network.h" #include "sldns/str2wire.h" @@ -88,6 +96,7 @@ #include "sldns/wire2str.h" #include "sldns/sbuffer.h" #include "util/timeval_func.h" +#include "util/tcp_conn_limit.h" #include "util/edns.h" #ifdef USE_CACHEDB #include "cachedb/cachedb.h" @@ -102,6 +111,9 @@ #ifdef HAVE_NETDB_H #include <netdb.h> #endif +#ifdef HAVE_POLL_H +#include <poll.h> +#endif /* just for portability */ #ifdef SQ @@ -114,6 +126,18 @@ /** Acceptable lengths of str lines */ #define MAX_CMD_STRLINE 1024 #define MAX_STDIN_STRLINE 2048 +/** What number of loop iterations is too much for ipc retries */ +#define IPC_LOOP_MAX 200 +/** Timeout in msec for ipc socket poll. */ +#define IPC_NOTIFICATION_WAIT 200 + +static void fr_printq_delete(struct fast_reload_printq* printq); +static void fr_main_perform_printout(struct fast_reload_thread* fr); +static int fr_printq_empty(struct fast_reload_printq* printq); +static void fr_printq_list_insert(struct fast_reload_printq* printq, + struct daemon* daemon); +static void fr_printq_remove(struct fast_reload_printq* printq); +static void fr_check_cmd_from_thread(struct fast_reload_thread* fr); static int remote_setup_ctx(struct daemon_remote* rc, struct config_file* cfg) @@ -512,6 +536,11 @@ state_list_remove_elem(struct rc_state** list, struct comm_point* c) static void clean_point(struct daemon_remote* rc, struct rc_state* s) { + if(!s->rc) { + /* the state has been picked up and moved away */ + free(s); + return; + } state_list_remove_elem(&rc->busy_list, s->c); rc->active --; if(s->ssl) { @@ -679,6 +708,65 @@ do_reload(RES* ssl, struct worker* worker, int reuse_cache) send_ok(ssl); } +#ifndef THREADS_DISABLED +/** parse fast reload command options. */ +static int +fr_parse_options(RES* ssl, char* arg, int* fr_verb, int* fr_nopause, + int* fr_drop_mesh) +{ + char* argp = arg; + while(*argp=='+') { + argp++; + while(*argp!=0 && *argp!=' ' && *argp!='\t') { + if(*argp == 'v') { + (*fr_verb)++; + } else if(*argp == 'p') { + (*fr_nopause) = 1; + } else if(*argp == 'd') { + (*fr_drop_mesh) = 1; + } else { + if(!ssl_printf(ssl, + "error: unknown option '+%c'\n", + *argp)) + return 0; + return 0; + } + argp++; + } + argp = skipwhite(argp); + } + if(*argp!=0) { + if(!ssl_printf(ssl, "error: unknown option '%s'\n", argp)) + return 0; + return 0; + } + return 1; +} +#endif /* !THREADS_DISABLED */ + +/** do the fast_reload command */ +static void +do_fast_reload(RES* ssl, struct worker* worker, struct rc_state* s, char* arg) +{ +#ifdef THREADS_DISABLED + if(!ssl_printf(ssl, "error: no threads for fast_reload, compiled without threads.\n")) + return; + (void)worker; + (void)s; + (void)arg; +#else + int fr_verb = 0, fr_nopause = 0, fr_drop_mesh = 0; + if(!fr_parse_options(ssl, arg, &fr_verb, &fr_nopause, &fr_drop_mesh)) + return; + if(fr_verb >= 1) { + if(!ssl_printf(ssl, "start fast_reload\n")) + return; + } + fast_reload_thread_start(ssl, worker, s, fr_verb, fr_nopause, + fr_drop_mesh); +#endif +} + /** do the verbosity command */ static void do_verbosity(RES* ssl, char* str) @@ -707,6 +795,10 @@ print_stats(RES* ssl, const char* nm, struct ub_stats_info* s) (unsigned long)s->svr.num_queries_cookie_client)) return 0; if(!ssl_printf(ssl, "%s.num.queries_cookie_invalid"SQ"%lu\n", nm, (unsigned long)s->svr.num_queries_cookie_invalid)) return 0; + if(!ssl_printf(ssl, "%s.num.queries_discard_timeout"SQ"%lu\n", nm, + (unsigned long)s->svr.num_queries_discard_timeout)) return 0; + if(!ssl_printf(ssl, "%s.num.queries_wait_limit"SQ"%lu\n", nm, + (unsigned long)s->svr.num_queries_wait_limit)) return 0; if(!ssl_printf(ssl, "%s.num.cachehits"SQ"%lu\n", nm, (unsigned long)(s->svr.num_queries - s->svr.num_queries_missed_cache))) return 0; @@ -732,6 +824,8 @@ print_stats(RES* ssl, const char* nm, struct ub_stats_info* s) if(!ssl_printf(ssl, "%s.num.dnscrypt.malformed"SQ"%lu\n", nm, (unsigned long)s->svr.num_query_dnscrypt_crypted_malformed)) return 0; #endif + if(!ssl_printf(ssl, "%s.num.dns_error_reports"SQ"%lu\n", nm, + (unsigned long)s->svr.num_dns_error_reports)) return 0; if(!ssl_printf(ssl, "%s.requestlist.avg"SQ"%g\n", nm, (s->svr.num_queries_missed_cache+s->svr.num_queries_prefetch)? (double)s->svr.sum_query_list_size/ @@ -1469,8 +1563,7 @@ do_view_zone_add(RES* ssl, struct worker* worker, char* arg) struct view* v; if(!find_arg2(ssl, arg, &arg2)) return; - v = views_find_view(worker->daemon->views, - arg, 1 /* get write lock*/); + v = views_find_view(worker->env.views, arg, 1 /* get write lock*/); if(!v) { ssl_printf(ssl,"no view with name: %s\n", arg); return; @@ -1502,8 +1595,7 @@ do_view_zone_remove(RES* ssl, struct worker* worker, char* arg) struct view* v; if(!find_arg2(ssl, arg, &arg2)) return; - v = views_find_view(worker->daemon->views, - arg, 1 /* get write lock*/); + v = views_find_view(worker->env.views, arg, 1 /* get write lock*/); if(!v) { ssl_printf(ssl,"no view with name: %s\n", arg); return; @@ -1525,8 +1617,7 @@ do_view_data_add(RES* ssl, struct worker* worker, char* arg) struct view* v; if(!find_arg2(ssl, arg, &arg2)) return; - v = views_find_view(worker->daemon->views, - arg, 1 /* get write lock*/); + v = views_find_view(worker->env.views, arg, 1 /* get write lock*/); if(!v) { ssl_printf(ssl,"no view with name: %s\n", arg); return; @@ -1551,8 +1642,7 @@ do_view_datas_add(struct daemon_remote* rc, RES* ssl, struct worker* worker, char buf[MAX_CMD_STRLINE + MAX_STDIN_STRLINE] = "view_local_data "; size_t cmd_len; int num = 0, line = 0; - v = views_find_view(worker->daemon->views, - arg, 1 /* get write lock*/); + v = views_find_view(worker->env.views, arg, 1 /* get write lock*/); if(!v) { ssl_printf(ssl,"no view with name: %s\n", arg); return; @@ -1593,8 +1683,7 @@ do_view_data_remove(RES* ssl, struct worker* worker, char* arg) struct view* v; if(!find_arg2(ssl, arg, &arg2)) return; - v = views_find_view(worker->daemon->views, - arg, 1 /* get write lock*/); + v = views_find_view(worker->env.views, arg, 1 /* get write lock*/); if(!v) { ssl_printf(ssl,"no view with name: %s\n", arg); return; @@ -1617,8 +1706,7 @@ do_view_datas_remove(struct daemon_remote* rc, RES* ssl, struct worker* worker, char buf[MAX_CMD_STRLINE + MAX_STDIN_STRLINE] = "view_local_data_remove "; int num = 0; size_t cmd_len; - v = views_find_view(worker->daemon->views, - arg, 1 /* get write lock*/); + v = views_find_view(worker->env.views, arg, 1 /* get write lock*/); if(!v) { ssl_printf(ssl,"no view with name: %s\n", arg); return; @@ -1946,7 +2034,7 @@ bogus_del_rrset(struct lruhash_entry* e, void* arg) /* entry is locked */ struct del_info* inf = (struct del_info*)arg; struct packed_rrset_data* d = (struct packed_rrset_data*)e->data; - if(d->security == sec_status_bogus) { + if(d->security == sec_status_bogus && d->ttl > inf->expired) { d->ttl = inf->expired; inf->num_rrsets++; } @@ -1959,7 +2047,7 @@ bogus_del_msg(struct lruhash_entry* e, void* arg) /* entry is locked */ struct del_info* inf = (struct del_info*)arg; struct reply_info* d = (struct reply_info*)e->data; - if(d->security == sec_status_bogus) { + if(d->security == sec_status_bogus && d->ttl > inf->expired) { d->ttl = inf->expired; d->prefetch_ttl = inf->expired; d->serve_expired_ttl = inf->expired; @@ -1979,7 +2067,7 @@ bogus_del_kcache(struct lruhash_entry* e, void* arg) /* entry is locked */ struct del_info* inf = (struct del_info*)arg; struct key_entry_data* d = (struct key_entry_data*)e->data; - if(d->isbad) { + if(d->isbad && d->ttl > inf->expired) { d->ttl = inf->expired; inf->num_keys++; } @@ -2028,7 +2116,8 @@ negative_del_rrset(struct lruhash_entry* e, void* arg) /* delete the parentside negative cache rrsets, * these are nameserver rrsets that failed lookup, rdata empty */ if((k->rk.flags & PACKED_RRSET_PARENT_SIDE) && d->count == 1 && - d->rrsig_count == 0 && d->rr_len[0] == 0) { + d->rrsig_count == 0 && d->rr_len[0] == 0 && + d->ttl > inf->expired) { d->ttl = inf->expired; inf->num_rrsets++; } @@ -2043,7 +2132,8 @@ negative_del_msg(struct lruhash_entry* e, void* arg) struct reply_info* d = (struct reply_info*)e->data; /* rcode not NOERROR: NXDOMAIN, SERVFAIL, ..: an nxdomain or error * or NOERROR rcode with ANCOUNT==0: a NODATA answer */ - if(FLAGS_GET_RCODE(d->flags) != 0 || d->an_numrrsets == 0) { + if((FLAGS_GET_RCODE(d->flags) != 0 || d->an_numrrsets == 0) && + d->ttl > inf->expired) { d->ttl = inf->expired; d->prefetch_ttl = inf->expired; d->serve_expired_ttl = inf->expired; @@ -2065,7 +2155,7 @@ negative_del_kcache(struct lruhash_entry* e, void* arg) struct key_entry_data* d = (struct key_entry_data*)e->data; /* could be bad because of lookup failure on the DS, DNSKEY, which * was nxdomain or servfail, and thus a result of negative lookups */ - if(d->isbad) { + if(d->isbad && d->ttl > inf->expired) { d->ttl = inf->expired; inf->num_keys++; } @@ -2137,7 +2227,7 @@ static int ssl_print_name_dp(RES* ssl, const char* str, uint8_t* nm, uint16_t dclass, struct delegpt* dp) { - char buf[257]; + char buf[LDNS_MAX_DOMAINLEN]; struct delegpt_ns* ns; struct delegpt_addr* a; int f = 0; @@ -2505,7 +2595,7 @@ do_insecure_remove(RES* ssl, struct worker* worker, char* arg) static void do_insecure_list(RES* ssl, struct worker* worker) { - char buf[257]; + char buf[LDNS_MAX_DOMAINLEN]; struct trust_anchor* a; if(worker->env.anchors) { RBTREE_FOR(a, struct trust_anchor*, worker->env.anchors->tree) { @@ -2602,7 +2692,7 @@ get_mesh_status(struct mesh_area* mesh, struct mesh_state* m, } } else if(s == module_wait_subquery) { /* look in subs from mesh state to see what */ - char nm[257]; + char nm[LDNS_MAX_DOMAINLEN]; struct mesh_state_ref* sub; snprintf(buf, len, "%s wants", modname); l = strlen(buf); @@ -2632,7 +2722,7 @@ do_dump_requestlist(RES* ssl, struct worker* worker) struct mesh_area* mesh; struct mesh_state* m; int num = 0; - char buf[257]; + char buf[LDNS_MAX_DOMAINLEN]; char timebuf[32]; char statbuf[10240]; if(!ssl_printf(ssl, "thread #%d\n", worker->thread_num)) @@ -2682,7 +2772,7 @@ dump_infra_host(struct lruhash_entry* e, void* arg) struct infra_key* k = (struct infra_key*)e->key; struct infra_data* d = (struct infra_data*)e->data; char ip_str[1024]; - char name[257]; + char name[LDNS_MAX_DOMAINLEN]; int port; if(a->ssl_failed) return; @@ -2949,7 +3039,7 @@ static void do_list_auth_zones(RES* ssl, struct auth_zones* az) { struct auth_zone* z; - char buf[257], buf2[256]; + char buf[LDNS_MAX_DOMAINLEN], buf2[256]; lock_rw_rdlock(&az->lock); RBTREE_FOR(z, struct auth_zone*, &az->ztree) { lock_rw_rdlock(&z->lock); @@ -2979,7 +3069,7 @@ static void do_list_local_zones(RES* ssl, struct local_zones* zones) { struct local_zone* z; - char buf[257]; + char buf[LDNS_MAX_DOMAINLEN]; lock_rw_rdlock(&zones->lock); RBTREE_FOR(z, struct local_zone*, &zones->ztree) { lock_rw_rdlock(&z->lock); @@ -3039,7 +3129,7 @@ do_list_local_data(RES* ssl, struct worker* worker, struct local_zones* zones) static void do_view_list_local_zones(RES* ssl, struct worker* worker, char* arg) { - struct view* v = views_find_view(worker->daemon->views, + struct view* v = views_find_view(worker->env.views, arg, 0 /* get read lock*/); if(!v) { ssl_printf(ssl,"no view with name: %s\n", arg); @@ -3055,7 +3145,7 @@ do_view_list_local_zones(RES* ssl, struct worker* worker, char* arg) static void do_view_list_local_data(RES* ssl, struct worker* worker, char* arg) { - struct view* v = views_find_view(worker->daemon->views, + struct view* v = views_find_view(worker->env.views, arg, 0 /* get read lock*/); if(!v) { ssl_printf(ssl,"no view with name: %s\n", arg); @@ -3090,7 +3180,7 @@ rate_list(struct lruhash_entry* e, void* arg) struct ratelimit_list_arg* a = (struct ratelimit_list_arg*)arg; struct rate_key* k = (struct rate_key*)e->key; struct rate_data* d = (struct rate_data*)e->data; - char buf[257]; + char buf[LDNS_MAX_DOMAINLEN]; int lim = infra_find_ratelimit(a->infra, k->name, k->namelen); int max = infra_rate_max(d, a->now, a->backoff); if(a->all == 0) { @@ -3421,7 +3511,7 @@ cmdcmp(char* p, const char* cmd, size_t len) /** execute a remote control command */ static void -execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd, +execute_cmd(struct daemon_remote* rc, struct rc_state* s, RES* ssl, char* cmd, struct worker* worker) { char* p = skipwhite(cmd); @@ -3435,6 +3525,9 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd, } else if(cmdcmp(p, "reload", 6)) { do_reload(ssl, worker, 0); return; + } else if(cmdcmp(p, "fast_reload", 11)) { + do_fast_reload(ssl, worker, s, skipwhite(p+11)); + return; } else if(cmdcmp(p, "stats_noreset", 13)) { do_stats(ssl, worker, 0); return; @@ -3633,7 +3726,7 @@ daemon_remote_exec(struct worker* worker) return; } verbose(VERB_ALGO, "remote exec distributed: %s", (char*)msg); - execute_cmd(NULL, NULL, (char*)msg, worker); + execute_cmd(NULL, NULL, NULL, (char*)msg, worker); free(msg); } @@ -3697,7 +3790,7 @@ handle_req(struct daemon_remote* rc, struct rc_state* s, RES* res) verbose(VERB_DETAIL, "control cmd: %s", buf); /* figure out what to do */ - execute_cmd(rc, res, buf, rc->worker); + execute_cmd(rc, s, res, buf, rc->worker); } /** handle SSL_do_handshake changes to the file descriptor to wait for later */ @@ -3789,3 +3882,4010 @@ int remote_control_callback(struct comm_point* c, void* arg, int err, clean_point(rc, s); return 0; } + +/** + * This routine polls a socket for readiness. + * @param fd: file descriptor, -1 uses no fd for a timer only. + * @param timeout: time in msec to wait. 0 means nonblocking test, + * -1 waits blocking for events. + * @param pollin: check for input event. + * @param pollout: check for output event. + * @param event: output variable, set to true if the event happens. + * It is false if there was an error or timeout. + * @return false is system call failure, also logged. + */ +static int +sock_poll_timeout(int fd, int timeout, int pollin, int pollout, int* event) +{ + int loopcount = 0; + /* Loop if the system call returns an errno to do so, like EINTR. */ + log_assert(pollin || pollout); + while(1) { + struct pollfd p, *fds; + int nfds, ret; + if(++loopcount > IPC_LOOP_MAX) { + log_err("sock_poll_timeout: loop"); + if(event) + *event = 0; + return 0; + } + if(fd == -1) { + fds = NULL; + nfds = 0; + } else { + fds = &p; + nfds = 1; + memset(&p, 0, sizeof(p)); + p.fd = fd; +#ifndef USE_WINSOCK + p.events = POLLERR + | POLLHUP + ; +#endif + if(pollin) + p.events |= POLLIN; + if(pollout) + p.events |= POLLOUT; + } +#ifndef USE_WINSOCK + ret = poll(fds, nfds, timeout); +#else + if(fds == NULL) { + Sleep(timeout); + ret = 0; + } else { + ret = WSAPoll(fds, nfds, timeout); + } +#endif + if(ret == -1) { +#ifndef USE_WINSOCK + if( + errno == EINTR || errno == EAGAIN +# ifdef EWOULDBLOCK + || errno == EWOULDBLOCK +# endif + ) continue; /* Try again. */ +#endif + /* For WSAPoll we only get errors here: + * o WSAENETDOWN + * o WSAEFAULT + * o WSAEINVAL + * o WSAENOBUFS + */ + log_err("poll: %s", sock_strerror(errno)); + if(event) + *event = 0; + return 0; + } else if(ret == 0) { + /* Timeout */ + if(event) + *event = 0; + return 1; + } + break; + } + if(event) + *event = 1; + return 1; +} + +/** fast reload convert fast reload notification status to string */ +static const char* +fr_notification_to_string(enum fast_reload_notification status) +{ + switch(status) { + case fast_reload_notification_none: + return "none"; + case fast_reload_notification_done: + return "done"; + case fast_reload_notification_done_error: + return "done_error"; + case fast_reload_notification_exit: + return "exit"; + case fast_reload_notification_exited: + return "exited"; + case fast_reload_notification_printout: + return "printout"; + case fast_reload_notification_reload_stop: + return "reload_stop"; + case fast_reload_notification_reload_ack: + return "reload_ack"; + case fast_reload_notification_reload_nopause_poll: + return "reload_nopause_poll"; + case fast_reload_notification_reload_start: + return "reload_start"; + default: + break; + } + return "unknown"; +} + +#ifndef THREADS_DISABLED +/** fast reload, poll for notification incoming. True if quit */ +static int +fr_poll_for_quit(struct fast_reload_thread* fr) +{ + int inevent, loopexit = 0, bcount = 0; + uint32_t cmd; + ssize_t ret; + + if(fr->need_to_quit) + return 1; + /* Is there data? */ + if(!sock_poll_timeout(fr->commpair[1], 0, 1, 0, &inevent)) { + log_err("fr_poll_for_quit: poll failed"); + return 0; + } + if(!inevent) + return 0; + + /* Read the data */ + while(1) { + if(++loopexit > IPC_LOOP_MAX) { + log_err("fr_poll_for_quit: recv loops %s", + sock_strerror(errno)); + return 0; + } + ret = recv(fr->commpair[1], ((char*)&cmd)+bcount, + sizeof(cmd)-bcount, 0); + if(ret == -1) { + if( +#ifndef USE_WINSOCK + errno == EINTR || errno == EAGAIN +# ifdef EWOULDBLOCK + || errno == EWOULDBLOCK +# endif +#else + WSAGetLastError() == WSAEINTR || + WSAGetLastError() == WSAEINPROGRESS || + WSAGetLastError() == WSAEWOULDBLOCK +#endif + ) + continue; /* Try again. */ + log_err("fr_poll_for_quit: recv: %s", + sock_strerror(errno)); + return 0; + } else if(ret+(ssize_t)bcount != sizeof(cmd)) { + bcount += ret; + if((size_t)bcount < sizeof(cmd)) + continue; + } + break; + } + if(cmd == fast_reload_notification_exit) { + fr->need_to_quit = 1; + verbose(VERB_ALGO, "fast reload: exit notification received"); + return 1; + } + log_err("fr_poll_for_quit: unknown notification status received: %d %s", + cmd, fr_notification_to_string(cmd)); + return 0; +} + +/** fast reload thread. Send notification from the fast reload thread */ +static void +fr_send_notification(struct fast_reload_thread* fr, + enum fast_reload_notification status) +{ + int outevent, loopexit = 0, bcount = 0; + uint32_t cmd; + ssize_t ret; + verbose(VERB_ALGO, "fast reload: send notification %s", + fr_notification_to_string(status)); + /* Make a blocking attempt to send. But meanwhile stay responsive, + * once in a while for quit commands. In case the server has to quit. */ + /* see if there is incoming quit signals */ + if(fr_poll_for_quit(fr)) + return; + cmd = status; + while(1) { + if(++loopexit > IPC_LOOP_MAX) { + log_err("fast reload: could not send notification"); + return; + } + /* wait for socket to become writable */ + if(!sock_poll_timeout(fr->commpair[1], IPC_NOTIFICATION_WAIT, + 0, 1, &outevent)) { + log_err("fast reload: poll failed"); + return; + } + if(fr_poll_for_quit(fr)) + return; + if(!outevent) + continue; + ret = send(fr->commpair[1], ((char*)&cmd)+bcount, + sizeof(cmd)-bcount, 0); + if(ret == -1) { + if( +#ifndef USE_WINSOCK + errno == EINTR || errno == EAGAIN +# ifdef EWOULDBLOCK + || errno == EWOULDBLOCK +# endif +#else + WSAGetLastError() == WSAEINTR || + WSAGetLastError() == WSAEINPROGRESS || + WSAGetLastError() == WSAEWOULDBLOCK +#endif + ) + continue; /* Try again. */ + log_err("fast reload send notification: send: %s", + sock_strerror(errno)); + return; + } else if(ret+(ssize_t)bcount != sizeof(cmd)) { + bcount += ret; + if((size_t)bcount < sizeof(cmd)) + continue; + } + break; + } +} + +/** fast reload thread queue up text string for output */ +static int +fr_output_text(struct fast_reload_thread* fr, const char* msg) +{ + char* item = strdup(msg); + if(!item) { + log_err("fast reload output text: strdup out of memory"); + return 0; + } + lock_basic_lock(&fr->fr_output_lock); + if(!cfg_strlist_append(fr->fr_output, item)) { + lock_basic_unlock(&fr->fr_output_lock); + /* The item is freed by cfg_strlist_append on failure. */ + log_err("fast reload output text: append out of memory"); + return 0; + } + lock_basic_unlock(&fr->fr_output_lock); + return 1; +} + +/** fast reload thread output vmsg function */ +static int +fr_output_vmsg(struct fast_reload_thread* fr, const char* format, va_list args) +{ + char msg[1024]; + vsnprintf(msg, sizeof(msg), format, args); + return fr_output_text(fr, msg); +} + +/** fast reload thread printout function, with printf arguments */ +static int fr_output_printf(struct fast_reload_thread* fr, + const char* format, ...) ATTR_FORMAT(printf, 2, 3); + +/** fast reload thread printout function, prints to list and signals + * the remote control thread to move that to get written to the socket + * of the remote control connection. */ +static int +fr_output_printf(struct fast_reload_thread* fr, const char* format, ...) +{ + va_list args; + int ret; + va_start(args, format); + ret = fr_output_vmsg(fr, format, args); + va_end(args); + return ret; +} + +/** fast reload thread, init time counters */ +static void +fr_init_time(struct timeval* time_start, struct timeval* time_read, + struct timeval* time_construct, struct timeval* time_reload, + struct timeval* time_end) +{ + memset(time_start, 0, sizeof(*time_start)); + memset(time_read, 0, sizeof(*time_read)); + memset(time_construct, 0, sizeof(*time_construct)); + memset(time_reload, 0, sizeof(*time_reload)); + memset(time_end, 0, sizeof(*time_end)); + if(gettimeofday(time_start, NULL) < 0) + log_err("gettimeofday: %s", strerror(errno)); +} + +/** + * Structure with constructed elements for use during fast reload. + * At the start it contains the tree items for the new config. + * After the tree items are swapped into the server, the old elements + * are kept in here. They can then be deleted. + */ +struct fast_reload_construct { + /** construct for views */ + struct views* views; + /** construct for auth zones */ + struct auth_zones* auth_zones; + /** construct for forwards */ + struct iter_forwards* fwds; + /** construct for stubs */ + struct iter_hints* hints; + /** construct for respip_set */ + struct respip_set* respip_set; + /** construct for access control */ + struct acl_list* acl; + /** construct for access control interface */ + struct acl_list* acl_interface; + /** construct for tcp connection limit */ + struct tcl_list* tcl; + /** construct for local zones */ + struct local_zones* local_zones; + /** if there is response ip configuration in use */ + int use_response_ip; + /** if there is an rpz zone */ + int use_rpz; + /** construct for edns strings */ + struct edns_strings* edns_strings; + /** construct for trust anchors */ + struct val_anchors* anchors; + /** construct for nsec3 key size */ + size_t* nsec3_keysize; + /** construct for nsec3 max iter */ + size_t* nsec3_maxiter; + /** construct for nsec3 keyiter count */ + int nsec3_keyiter_count; + /** construct for target fetch policy */ + int* target_fetch_policy; + /** construct for max dependency depth */ + int max_dependency_depth; + /** construct for donotquery addresses */ + struct iter_donotq* donotq; + /** construct for private addresses and domains */ + struct iter_priv* priv; + /** construct whitelist for capsforid names */ + struct rbtree_type* caps_white; + /** construct for nat64 */ + struct iter_nat64 nat64; + /** construct for wait_limits_netblock */ + struct rbtree_type wait_limits_netblock; + /** construct for wait_limits_cookie_netblock */ + struct rbtree_type wait_limits_cookie_netblock; + /** construct for domain limits */ + struct rbtree_type domain_limits; + /** storage for the old configuration elements. The outer struct + * is allocated with malloc here, the items are from config. */ + struct config_file* oldcfg; +}; + +/** fast reload thread, read config */ +static int +fr_read_config(struct fast_reload_thread* fr, struct config_file** newcfg) +{ + /* Create new config structure. */ + *newcfg = config_create(); + if(!*newcfg) { + if(!fr_output_printf(fr, "config_create failed: out of memory\n")) + return 0; + fr_send_notification(fr, fast_reload_notification_printout); + return 0; + } + if(fr_poll_for_quit(fr)) + return 1; + + /* Read new config from file */ + if(!config_read(*newcfg, fr->worker->daemon->cfgfile, + fr->worker->daemon->chroot)) { + config_delete(*newcfg); + if(!fr_output_printf(fr, "config_read %s%s%s%s failed: %s\n", + (fr->worker->daemon->chroot?"<chroot:":""), + (fr->worker->daemon->chroot?fr->worker->daemon->chroot:""), + (fr->worker->daemon->chroot?"> ":""), + fr->worker->daemon->cfgfile, strerror(errno))) + return 0; + fr_send_notification(fr, fast_reload_notification_printout); + return 0; + } + if(fr_poll_for_quit(fr)) + return 1; + if(fr->fr_verb >= 1) { + if(!fr_output_printf(fr, "done read config file %s%s%s%s\n", + (fr->worker->daemon->chroot?"<chroot:":""), + (fr->worker->daemon->chroot?fr->worker->daemon->chroot:""), + (fr->worker->daemon->chroot?"> ":""), + fr->worker->daemon->cfgfile)) + return 0; + fr_send_notification(fr, fast_reload_notification_printout); + } + + return 1; +} + +/** Check if two taglists are equal. */ +static int +taglist_equal(char** tagname_a, int num_tags_a, char** tagname_b, + int num_tags_b) +{ + int i; + if(num_tags_a != num_tags_b) + return 0; + for(i=0; i<num_tags_a; i++) { + if(strcmp(tagname_a[i], tagname_b[i]) != 0) + return 0; + } + return 1; +} + +/** Check the change from a to b is only new entries at the end. */ +static int +taglist_change_at_end(char** tagname_a, int num_tags_a, char** tagname_b, + int num_tags_b) +{ + if(num_tags_a < 0 || num_tags_b < 0) + return 0; + if(num_tags_a >= num_tags_b) + return 0; + /* So, b is longer than a. Check if the initial start of the two + * taglists is the same. */ + if(!taglist_equal(tagname_a, num_tags_a, tagname_b, num_tags_a)) + return 0; + return 1; +} + +/** fast reload thread, check tag defines. */ +static int +fr_check_tag_defines(struct fast_reload_thread* fr, struct config_file* newcfg) +{ + /* The tags are kept in a bitlist for items. Some of them are stored + * in query info. If the tags change, then the old values are + * inaccurate. The solution is to then flush the query list. + * Unless the change only involves adding new tags at the end, that + * needs no changes. */ + if(!taglist_equal(fr->worker->daemon->cfg->tagname, + fr->worker->daemon->cfg->num_tags, newcfg->tagname, + newcfg->num_tags) && + !taglist_change_at_end(fr->worker->daemon->cfg->tagname, + fr->worker->daemon->cfg->num_tags, newcfg->tagname, + newcfg->num_tags)) { + /* The tags have changed too much, the define-tag config. */ + if(fr->fr_drop_mesh) + return 1; /* already dropping queries */ + fr->fr_drop_mesh = 1; + fr->worker->daemon->fast_reload_drop_mesh = fr->fr_drop_mesh; + if(!fr_output_printf(fr, "tags have changed, with " + "'define-tag', and the queries have to be dropped " + "for consistency, setting '+d'\n")) + return 0; + fr_send_notification(fr, fast_reload_notification_printout); + } + return 1; +} + +/** fast reload thread, check if config item has changed, if not add to + * the explanatory string. */ +static void +fr_check_changed_cfg(int cmp, const char* desc, char* str, size_t len) +{ + if(cmp) { + size_t slen = strlen(str); + size_t desclen = strlen(desc); + if(slen == 0) { + snprintf(str, len, "%s", desc); + return; + } + if(len - slen < desclen+2) + return; /* It does not fit */ + snprintf(str+slen, len-slen, " %s", desc); + } +} + +/** fast reload thread, check if config string has changed, checks NULLs. */ +static void +fr_check_changed_cfg_str(char* cmp1, char* cmp2, const char* desc, char* str, + size_t len) +{ + if((!cmp1 && cmp2) || + (cmp1 && !cmp2) || + (cmp1 && cmp2 && strcmp(cmp1, cmp2) != 0)) { + fr_check_changed_cfg(1, desc, str, len); + } +} + +/** fast reload thread, check if config strlist has changed. */ +static void +fr_check_changed_cfg_strlist(struct config_strlist* cmp1, + struct config_strlist* cmp2, const char* desc, char* str, size_t len) +{ + struct config_strlist* p1 = cmp1, *p2 = cmp2; + while(p1 && p2) { + if((!p1->str && p2->str) || + (p1->str && !p2->str) || + (p1->str && p2->str && strcmp(p1->str, p2->str) != 0)) { + /* The strlist is different. */ + fr_check_changed_cfg(1, desc, str, len); + return; + } + p1 = p1->next; + p2 = p2->next; + } + if((!p1 && p2) || (p1 && !p2)) { + fr_check_changed_cfg(1, desc, str, len); + } +} + +/** fast reload thread, check if config str2list has changed. */ +static void +fr_check_changed_cfg_str2list(struct config_str2list* cmp1, + struct config_str2list* cmp2, const char* desc, char* str, size_t len) +{ + struct config_str2list* p1 = cmp1, *p2 = cmp2; + while(p1 && p2) { + if((!p1->str && p2->str) || + (p1->str && !p2->str) || + (p1->str && p2->str && strcmp(p1->str, p2->str) != 0)) { + /* The str2list is different. */ + fr_check_changed_cfg(1, desc, str, len); + return; + } + if((!p1->str2 && p2->str2) || + (p1->str2 && !p2->str2) || + (p1->str2 && p2->str2 && + strcmp(p1->str2, p2->str2) != 0)) { + /* The str2list is different. */ + fr_check_changed_cfg(1, desc, str, len); + return; + } + p1 = p1->next; + p2 = p2->next; + } + if((!p1 && p2) || (p1 && !p2)) { + fr_check_changed_cfg(1, desc, str, len); + } +} + +/** fast reload thread, check compatible config items */ +static int +fr_check_compat_cfg(struct fast_reload_thread* fr, struct config_file* newcfg) +{ + int i; + char changed_str[1024]; + struct config_file* cfg = fr->worker->env.cfg; + changed_str[0]=0; + + /* Find incompatible options, and if so, print an error. */ + fr_check_changed_cfg(cfg->num_threads != newcfg->num_threads, + "num-threads", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->do_ip4 != newcfg->do_ip4, + "do-ip4", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->do_ip6 != newcfg->do_ip6, + "do-ip6", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->do_udp != newcfg->do_udp, + "do-udp", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->do_tcp != newcfg->do_tcp, + "do-tcp", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->port != newcfg->port, + "port", changed_str, sizeof(changed_str)); + /* But cfg->outgoing_num_ports has been changed at startup, + * possibly to reduce it, so do not check it here. */ + fr_check_changed_cfg(cfg->outgoing_num_tcp != newcfg->outgoing_num_tcp, + "outgoing-num-tcp", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->incoming_num_tcp != newcfg->incoming_num_tcp, + "incoming-num-tcp", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->num_out_ifs != newcfg->num_out_ifs, + "outgoing-interface", changed_str, sizeof(changed_str)); + if(cfg->num_out_ifs == newcfg->num_out_ifs) { + for(i=0; i<cfg->num_out_ifs; i++) + fr_check_changed_cfg(strcmp(cfg->out_ifs[i], + newcfg->out_ifs[i]) != 0, "outgoing-interface", + changed_str, sizeof(changed_str)); + } + fr_check_changed_cfg(cfg->num_ifs != newcfg->num_ifs, + "interface", changed_str, sizeof(changed_str)); + if(cfg->num_ifs == newcfg->num_ifs) { + for(i=0; i<cfg->num_ifs; i++) + fr_check_changed_cfg(strcmp(cfg->ifs[i], + newcfg->ifs[i]) != 0, "interface", + changed_str, sizeof(changed_str)); + } + fr_check_changed_cfg(cfg->if_automatic != newcfg->if_automatic, + "interface-automatic", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->so_rcvbuf != newcfg->so_rcvbuf, + "so-rcvbuf", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->so_sndbuf != newcfg->so_sndbuf, + "so-sndbuf", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->so_reuseport != newcfg->so_reuseport, + "so-reuseport", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->ip_transparent != newcfg->ip_transparent, + "ip-transparent", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->ip_freebind != newcfg->ip_freebind, + "ip-freebind", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->udp_connect != newcfg->udp_connect, + "udp-connect", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->msg_buffer_size != newcfg->msg_buffer_size, + "msg-buffer-size", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->do_tcp_keepalive != newcfg->do_tcp_keepalive, + "edns-tcp-keepalive", changed_str, sizeof(changed_str)); + fr_check_changed_cfg( + cfg->tcp_keepalive_timeout != newcfg->tcp_keepalive_timeout, + "edns-tcp-keepalive-timeout", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->tcp_idle_timeout != newcfg->tcp_idle_timeout, + "tcp-idle-timeout", changed_str, sizeof(changed_str)); + /* Not changed, only if DoH is used, it is then stored in commpoints, + * as well as used from cfg. */ + fr_check_changed_cfg( + cfg->harden_large_queries != newcfg->harden_large_queries, + "harden-large-queries", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->http_max_streams != newcfg->http_max_streams, + "http-max-streams", changed_str, sizeof(changed_str)); + fr_check_changed_cfg_str(cfg->http_endpoint, newcfg->http_endpoint, + "http-endpoint", changed_str, sizeof(changed_str)); + fr_check_changed_cfg( + cfg->http_notls_downstream != newcfg->http_notls_downstream, + "http_notls_downstream", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->https_port != newcfg->https_port, + "https-port", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->ssl_port != newcfg->ssl_port, + "tls-port", changed_str, sizeof(changed_str)); + fr_check_changed_cfg_str(cfg->ssl_service_key, newcfg->ssl_service_key, + "tls-service-key", changed_str, sizeof(changed_str)); + fr_check_changed_cfg_str(cfg->ssl_service_pem, newcfg->ssl_service_pem, + "tls-service-pem", changed_str, sizeof(changed_str)); + fr_check_changed_cfg_str(cfg->tls_cert_bundle, newcfg->tls_cert_bundle, + "tls-cert-bundle", changed_str, sizeof(changed_str)); + fr_check_changed_cfg_strlist(cfg->proxy_protocol_port, + newcfg->proxy_protocol_port, "proxy-protocol-port", + changed_str, sizeof(changed_str)); + fr_check_changed_cfg_strlist(cfg->tls_additional_port, + newcfg->tls_additional_port, "tls-additional-port", + changed_str, sizeof(changed_str)); + fr_check_changed_cfg_str(cfg->if_automatic_ports, + newcfg->if_automatic_ports, "interface-automatic-ports", + changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->udp_upstream_without_downstream != + newcfg->udp_upstream_without_downstream, + "udp-upstream-without-downstream", changed_str, + sizeof(changed_str)); + + if(changed_str[0] != 0) { + /* The new config changes some items that do not work with + * fast reload. */ + if(!fr_output_printf(fr, "The config changes items that are " + "not compatible with fast_reload, perhaps do reload " + "or restart: %s", changed_str) || + !fr_output_printf(fr, "\n")) + return 0; + fr_send_notification(fr, fast_reload_notification_printout); + return 0; + } + return 1; +} + +/** fast reload thread, check nopause config items */ +static int +fr_check_nopause_cfg(struct fast_reload_thread* fr, struct config_file* newcfg) +{ + char changed_str[1024]; + struct config_file* cfg = fr->worker->env.cfg; + if(!fr->fr_nopause) + return 1; /* The nopause is not enabled, so no problem. */ + changed_str[0]=0; + + /* Check for iter_env. */ + fr_check_changed_cfg( + cfg->outbound_msg_retry != newcfg->outbound_msg_retry, + "outbound-msg-retry", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->max_sent_count != newcfg->max_sent_count, + "max-sent-count", changed_str, sizeof(changed_str)); + fr_check_changed_cfg( + cfg->max_query_restarts != newcfg->max_query_restarts, + "max-query-restarts", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(strcmp(cfg->target_fetch_policy, + newcfg->target_fetch_policy) != 0, + "target-fetch-policy", changed_str, sizeof(changed_str)); + fr_check_changed_cfg( + cfg->donotquery_localhost != newcfg->donotquery_localhost, + "do-not-query-localhost", changed_str, sizeof(changed_str)); + fr_check_changed_cfg_strlist(cfg->donotqueryaddrs, + newcfg->donotqueryaddrs, "do-not-query-localhost", + changed_str, sizeof(changed_str)); + fr_check_changed_cfg_strlist(cfg->private_address, + newcfg->private_address, "private-address", + changed_str, sizeof(changed_str)); + fr_check_changed_cfg_strlist(cfg->private_domain, + newcfg->private_domain, "private-domain", + changed_str, sizeof(changed_str)); + fr_check_changed_cfg_strlist(cfg->caps_whitelist, + newcfg->caps_whitelist, "caps-exempt", + changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->do_nat64 != newcfg->do_nat64, + "do-nat64", changed_str, sizeof(changed_str)); + fr_check_changed_cfg_str(cfg->nat64_prefix, newcfg->nat64_prefix, + "nat64-prefix", changed_str, sizeof(changed_str)); + + /* Check for val_env. */ + fr_check_changed_cfg(cfg->bogus_ttl != newcfg->bogus_ttl, + "val-bogus-ttl", changed_str, sizeof(changed_str)); + fr_check_changed_cfg( + cfg->val_date_override != newcfg->val_date_override, + "val-date-override", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->val_sig_skew_min != newcfg->val_sig_skew_min, + "val-sig-skew-min", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->val_sig_skew_max != newcfg->val_sig_skew_max, + "val-sig-skew-max", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(cfg->val_max_restart != newcfg->val_max_restart, + "val-max-restart", changed_str, sizeof(changed_str)); + fr_check_changed_cfg(strcmp(cfg->val_nsec3_key_iterations, + newcfg->val_nsec3_key_iterations) != 0, + "val-nsec3-keysize-iterations", changed_str, + sizeof(changed_str)); + + /* Check for infra. */ + fr_check_changed_cfg(cfg->host_ttl != newcfg->host_ttl, + "infra-host-ttl", changed_str, sizeof(changed_str)); + fr_check_changed_cfg( + cfg->infra_keep_probing != newcfg->infra_keep_probing, + "infra-keep-probing", changed_str, sizeof(changed_str)); + fr_check_changed_cfg( + cfg->ratelimit != newcfg->ratelimit, + "ratelimit", changed_str, sizeof(changed_str)); + fr_check_changed_cfg( + cfg->ip_ratelimit != newcfg->ip_ratelimit, + "ip-ratelimit", changed_str, sizeof(changed_str)); + fr_check_changed_cfg( + cfg->ip_ratelimit_cookie != newcfg->ip_ratelimit_cookie, + "ip-ratelimit-cookie", changed_str, sizeof(changed_str)); + fr_check_changed_cfg_str2list(cfg->wait_limit_netblock, + newcfg->wait_limit_netblock, "wait-limit-netblock", + changed_str, sizeof(changed_str)); + fr_check_changed_cfg_str2list(cfg->wait_limit_cookie_netblock, + newcfg->wait_limit_cookie_netblock, + "wait-limit-cookie-netblock", changed_str, + sizeof(changed_str)); + fr_check_changed_cfg_str2list(cfg->ratelimit_below_domain, + newcfg->ratelimit_below_domain, "ratelimit-below-domain", + changed_str, sizeof(changed_str)); + fr_check_changed_cfg_str2list(cfg->ratelimit_for_domain, + newcfg->ratelimit_for_domain, "ratelimit-for-domain", + changed_str, sizeof(changed_str)); + + /* Check for dnstap. */ + fr_check_changed_cfg( + cfg->dnstap_send_identity != newcfg->dnstap_send_identity, + "dnstap-send-identity", changed_str, sizeof(changed_str)); + fr_check_changed_cfg( + cfg->dnstap_send_version != newcfg->dnstap_send_version, + "dnstap-send-version", changed_str, sizeof(changed_str)); + fr_check_changed_cfg_str(cfg->dnstap_identity, newcfg->dnstap_identity, + "dnstap-identity", changed_str, sizeof(changed_str)); + fr_check_changed_cfg_str(cfg->dnstap_version, newcfg->dnstap_version, + "dnstap-version", changed_str, sizeof(changed_str)); + + if(changed_str[0] != 0) { + /* The new config changes some items that need a pause, + * to be able to update the variables. */ + if(!fr_output_printf(fr, "The config changes items that need " + "the fast_reload +p option, for nopause, " + "disabled to be reloaded: %s", changed_str) || + !fr_output_printf(fr, "\n")) + return 0; + fr_send_notification(fr, fast_reload_notification_printout); + return 0; + } + return 1; +} + +/** fast reload thread, clear construct information, deletes items */ +static void +fr_construct_clear(struct fast_reload_construct* ct) +{ + if(!ct) + return; + auth_zones_delete(ct->auth_zones); + forwards_delete(ct->fwds); + hints_delete(ct->hints); + respip_set_delete(ct->respip_set); + local_zones_delete(ct->local_zones); + acl_list_delete(ct->acl); + acl_list_delete(ct->acl_interface); + tcl_list_delete(ct->tcl); + edns_strings_delete(ct->edns_strings); + anchors_delete(ct->anchors); + views_delete(ct->views); + free(ct->nsec3_keysize); + free(ct->nsec3_maxiter); + free(ct->target_fetch_policy); + donotq_delete(ct->donotq); + priv_delete(ct->priv); + caps_white_delete(ct->caps_white); + wait_limits_free(&ct->wait_limits_netblock); + wait_limits_free(&ct->wait_limits_cookie_netblock); + domain_limits_free(&ct->domain_limits); + /* Delete the log identity here so that the global value is not + * reset by config_delete. */ + if(ct->oldcfg && ct->oldcfg->log_identity) { + free(ct->oldcfg->log_identity); + ct->oldcfg->log_identity = NULL; + } + config_delete(ct->oldcfg); +} + +/** get memory for strlist */ +static size_t +getmem_config_strlist(struct config_strlist* p) +{ + size_t m = 0; + struct config_strlist* s; + for(s = p; s; s = s->next) + m += sizeof(*s) + getmem_str(s->str); + return m; +} + +/** get memory for str2list */ +static size_t +getmem_config_str2list(struct config_str2list* p) +{ + size_t m = 0; + struct config_str2list* s; + for(s = p; s; s = s->next) + m += sizeof(*s) + getmem_str(s->str) + getmem_str(s->str2); + return m; +} + +/** get memory for str3list */ +static size_t +getmem_config_str3list(struct config_str3list* p) +{ + size_t m = 0; + struct config_str3list* s; + for(s = p; s; s = s->next) + m += sizeof(*s) + getmem_str(s->str) + getmem_str(s->str2) + + getmem_str(s->str3); + return m; +} + +/** get memory for strbytelist */ +static size_t +getmem_config_strbytelist(struct config_strbytelist* p) +{ + size_t m = 0; + struct config_strbytelist* s; + for(s = p; s; s = s->next) + m += sizeof(*s) + getmem_str(s->str) + (s->str2?s->str2len:0); + return m; +} + +/** get memory used by ifs array */ +static size_t +getmem_ifs(int numifs, char** ifs) +{ + size_t m = 0; + int i; + m += numifs * sizeof(char*); + for(i=0; i<numifs; i++) + m += getmem_str(ifs[i]); + return m; +} + +/** get memory for config_stub */ +static size_t +getmem_config_stub(struct config_stub* p) +{ + size_t m = 0; + struct config_stub* s; + for(s = p; s; s = s->next) + m += sizeof(*s) + getmem_str(s->name) + + getmem_config_strlist(s->hosts) + + getmem_config_strlist(s->addrs); + return m; +} + +/** get memory for config_auth */ +static size_t +getmem_config_auth(struct config_auth* p) +{ + size_t m = 0; + struct config_auth* s; + for(s = p; s; s = s->next) + m += sizeof(*s) + getmem_str(s->name) + + getmem_config_strlist(s->masters) + + getmem_config_strlist(s->urls) + + getmem_config_strlist(s->allow_notify) + + getmem_str(s->zonefile) + + s->rpz_taglistlen + + getmem_str(s->rpz_action_override) + + getmem_str(s->rpz_log_name) + + getmem_str(s->rpz_cname); + return m; +} + +/** get memory for config_view */ +static size_t +getmem_config_view(struct config_view* p) +{ + size_t m = 0; + struct config_view* s; + for(s = p; s; s = s->next) + m += sizeof(*s) + getmem_str(s->name) + + getmem_config_str2list(s->local_zones) + + getmem_config_strlist(s->local_data) + + getmem_config_strlist(s->local_zones_nodefault) +#ifdef USE_IPSET + + getmem_config_strlist(s->local_zones_ipset) +#endif + + getmem_config_str2list(s->respip_actions) + + getmem_config_str2list(s->respip_data); + + return m; +} + +/** get memory used by config_file item, estimate */ +static size_t +config_file_getmem(struct config_file* cfg) +{ + size_t m = 0; + m += sizeof(*cfg); + m += getmem_config_strlist(cfg->proxy_protocol_port); + m += getmem_str(cfg->ssl_service_key); + m += getmem_str(cfg->ssl_service_pem); + m += getmem_str(cfg->tls_cert_bundle); + m += getmem_config_strlist(cfg->tls_additional_port); + m += getmem_config_strlist(cfg->tls_session_ticket_keys.first); + m += getmem_str(cfg->tls_ciphers); + m += getmem_str(cfg->tls_ciphersuites); + m += getmem_str(cfg->http_endpoint); + m += (cfg->outgoing_avail_ports?65536*sizeof(int):0); + m += getmem_str(cfg->target_fetch_policy); + m += getmem_str(cfg->if_automatic_ports); + m += getmem_ifs(cfg->num_ifs, cfg->ifs); + m += getmem_ifs(cfg->num_out_ifs, cfg->out_ifs); + m += getmem_config_strlist(cfg->root_hints); + m += getmem_config_stub(cfg->stubs); + m += getmem_config_stub(cfg->forwards); + m += getmem_config_auth(cfg->auths); + m += getmem_config_view(cfg->views); + m += getmem_config_strlist(cfg->donotqueryaddrs); +#ifdef CLIENT_SUBNET + m += getmem_config_strlist(cfg->client_subnet); + m += getmem_config_strlist(cfg->client_subnet_zone); +#endif + m += getmem_config_str2list(cfg->acls); + m += getmem_config_str2list(cfg->tcp_connection_limits); + m += getmem_config_strlist(cfg->caps_whitelist); + m += getmem_config_strlist(cfg->private_address); + m += getmem_config_strlist(cfg->private_domain); + m += getmem_str(cfg->chrootdir); + m += getmem_str(cfg->username); + m += getmem_str(cfg->directory); + m += getmem_str(cfg->logfile); + m += getmem_str(cfg->pidfile); + m += getmem_str(cfg->log_identity); + m += getmem_str(cfg->identity); + m += getmem_str(cfg->version); + m += getmem_str(cfg->http_user_agent); + m += getmem_str(cfg->nsid_cfg_str); + m += (cfg->nsid?cfg->nsid_len:0); + m += getmem_str(cfg->module_conf); + m += getmem_config_strlist(cfg->trust_anchor_file_list); + m += getmem_config_strlist(cfg->trust_anchor_list); + m += getmem_config_strlist(cfg->auto_trust_anchor_file_list); + m += getmem_config_strlist(cfg->trusted_keys_file_list); + m += getmem_config_strlist(cfg->domain_insecure); + m += getmem_str(cfg->val_nsec3_key_iterations); + m += getmem_config_str2list(cfg->local_zones); + m += getmem_config_strlist(cfg->local_zones_nodefault); +#ifdef USE_IPSET + m += getmem_config_strlist(cfg->local_zones_ipset); +#endif + m += getmem_config_strlist(cfg->local_data); + m += getmem_config_str3list(cfg->local_zone_overrides); + m += getmem_config_strbytelist(cfg->local_zone_tags); + m += getmem_config_strbytelist(cfg->acl_tags); + m += getmem_config_str3list(cfg->acl_tag_actions); + m += getmem_config_str3list(cfg->acl_tag_datas); + m += getmem_config_str2list(cfg->acl_view); + m += getmem_config_str2list(cfg->interface_actions); + m += getmem_config_strbytelist(cfg->interface_tags); + m += getmem_config_str3list(cfg->interface_tag_actions); + m += getmem_config_str3list(cfg->interface_tag_datas); + m += getmem_config_str2list(cfg->interface_view); + m += getmem_config_strbytelist(cfg->respip_tags); + m += getmem_config_str2list(cfg->respip_actions); + m += getmem_config_str2list(cfg->respip_data); + m += getmem_ifs(cfg->num_tags, cfg->tagname); + m += getmem_config_strlist(cfg->control_ifs.first); + m += getmem_str(cfg->server_key_file); + m += getmem_str(cfg->server_cert_file); + m += getmem_str(cfg->control_key_file); + m += getmem_str(cfg->control_cert_file); + m += getmem_config_strlist(cfg->python_script); + m += getmem_config_strlist(cfg->dynlib_file); + m += getmem_str(cfg->dns64_prefix); + m += getmem_config_strlist(cfg->dns64_ignore_aaaa); + m += getmem_str(cfg->nat64_prefix); + m += getmem_str(cfg->dnstap_socket_path); + m += getmem_str(cfg->dnstap_ip); + m += getmem_str(cfg->dnstap_tls_server_name); + m += getmem_str(cfg->dnstap_tls_cert_bundle); + m += getmem_str(cfg->dnstap_tls_client_key_file); + m += getmem_str(cfg->dnstap_tls_client_cert_file); + m += getmem_str(cfg->dnstap_identity); + m += getmem_str(cfg->dnstap_version); + m += getmem_config_str2list(cfg->ratelimit_for_domain); + m += getmem_config_str2list(cfg->ratelimit_below_domain); + m += getmem_config_str2list(cfg->edns_client_strings); + m += getmem_str(cfg->dnscrypt_provider); + m += getmem_config_strlist(cfg->dnscrypt_secret_key); + m += getmem_config_strlist(cfg->dnscrypt_provider_cert); + m += getmem_config_strlist(cfg->dnscrypt_provider_cert_rotated); +#ifdef USE_IPSECMOD + m += getmem_config_strlist(cfg->ipsecmod_whitelist); + m += getmem_str(cfg->ipsecmod_hook); +#endif +#ifdef USE_CACHEDB + m += getmem_str(cfg->cachedb_backend); + m += getmem_str(cfg->cachedb_secret); +#ifdef USE_REDIS + m += getmem_str(cfg->redis_server_host); + m += getmem_str(cfg->redis_replica_server_host); + m += getmem_str(cfg->redis_server_path); + m += getmem_str(cfg->redis_replica_server_path); + m += getmem_str(cfg->redis_server_password); + m += getmem_str(cfg->redis_replica_server_password); +#endif +#endif +#ifdef USE_IPSET + m += getmem_str(cfg->ipset_name_v4); + m += getmem_str(cfg->ipset_name_v6); +#endif + return m; +} + +/** fast reload thread, print memory used by construct of items. */ +static int +fr_printmem(struct fast_reload_thread* fr, + struct config_file* newcfg, struct fast_reload_construct* ct) +{ + size_t mem = 0; + if(fr_poll_for_quit(fr)) + return 1; + mem += views_get_mem(ct->views); + mem += respip_set_get_mem(ct->respip_set); + mem += auth_zones_get_mem(ct->auth_zones); + mem += forwards_get_mem(ct->fwds); + mem += hints_get_mem(ct->hints); + mem += local_zones_get_mem(ct->local_zones); + mem += acl_list_get_mem(ct->acl); + mem += acl_list_get_mem(ct->acl_interface); + mem += tcl_list_get_mem(ct->tcl); + mem += edns_strings_get_mem(ct->edns_strings); + mem += anchors_get_mem(ct->anchors); + mem += sizeof(*ct->oldcfg); + mem += config_file_getmem(newcfg); + + if(!fr_output_printf(fr, "memory use %d bytes\n", (int)mem)) + return 0; + fr_send_notification(fr, fast_reload_notification_printout); + + return 1; +} + +/** fast reload thread, setup the acl_interface for the ports that + * the server has. */ +static int +ct_acl_interface_setup_ports(struct acl_list* acl_interface, + struct daemon* daemon) +{ + /* clean acl_interface */ + acl_interface_init(acl_interface); + if(!setup_acl_for_ports(acl_interface, daemon->ports[0])) + return 0; + if(daemon->reuseport) { + size_t i; + for(i=1; i<daemon->num_ports; i++) { + if(!setup_acl_for_ports(acl_interface, + daemon->ports[i])) + return 0; + } + } + return 1; +} + +/** fast reload, add new change to list of auth zones */ +static int +fr_add_auth_zone_change(struct fast_reload_thread* fr, struct auth_zone* old_z, + struct auth_zone* new_z, int is_deleted, int is_added, int is_changed) +{ + struct fast_reload_auth_change* item; + item = calloc(1, sizeof(*item)); + if(!item) { + log_err("malloc failure in add auth zone change"); + return 0; + } + item->old_z = old_z; + item->new_z = new_z; + item->is_deleted = is_deleted; + item->is_added = is_added; + item->is_changed = is_changed; + + item->next = fr->auth_zone_change_list; + fr->auth_zone_change_list = item; + return 1; +} + +/** See if auth master is equal */ +static int +xfr_auth_master_equal(struct auth_master* m1, struct auth_master* m2) +{ + if(!m1 && !m2) + return 1; + if(!m1 || !m2) + return 0; + + if((m1->host && !m2->host) || (!m1->host && m2->host)) + return 0; + if(m1->host && m2->host && strcmp(m1->host, m2->host) != 0) + return 0; + + if((m1->file && !m2->file) || (!m1->file && m2->file)) + return 0; + if(m1->file && m2->file && strcmp(m1->file, m2->file) != 0) + return 0; + + if((m1->http && !m2->http) || (!m1->http && m2->http)) + return 0; + if((m1->ixfr && !m2->ixfr) || (!m1->ixfr && m2->ixfr)) + return 0; + if((m1->allow_notify && !m2->allow_notify) || (!m1->allow_notify && m2->allow_notify)) + return 0; + if((m1->ssl && !m2->ssl) || (!m1->ssl && m2->ssl)) + return 0; + if(m1->port != m2->port) + return 0; + return 1; +} + +/** See if list of auth masters is equal */ +static int +xfr_masterlist_equal(struct auth_master* list1, struct auth_master* list2) +{ + struct auth_master* p1 = list1, *p2 = list2; + while(p1 && p2) { + if(!xfr_auth_master_equal(p1, p2)) + return 0; + p1 = p1->next; + p2 = p2->next; + } + if(!p1 && !p2) + return 1; + return 0; +} + +/** See if the list of masters has changed. */ +static int +xfr_masters_equal(struct auth_xfer* xfr1, struct auth_xfer* xfr2) +{ + if(xfr1 == NULL && xfr2 == NULL) + return 1; + if(xfr1 == NULL && xfr2 != NULL) + return 0; + if(xfr1 != NULL && xfr2 == NULL) + return 0; + if(xfr_masterlist_equal(xfr1->task_probe->masters, + xfr2->task_probe->masters) && + xfr_masterlist_equal(xfr1->task_transfer->masters, + xfr2->task_transfer->masters)) + return 1; + return 0; +} + +/** Check what has changed in auth zones, like added and deleted zones */ +static int +auth_zones_check_changes(struct fast_reload_thread* fr, + struct fast_reload_construct* ct) +{ + /* Check every zone in turn. */ + struct auth_zone* new_z, *old_z; + struct module_env* env = &fr->worker->env; + + fr->old_auth_zones = ct->auth_zones; + /* Nobody is using the new ct version yet. + * Also the ct lock is picked up before the env lock for auth_zones. */ + lock_rw_rdlock(&ct->auth_zones->lock); + + /* Find deleted zones by looping over the current list and looking + * up in the new tree. */ + lock_rw_rdlock(&env->auth_zones->lock); + RBTREE_FOR(old_z, struct auth_zone*, &env->auth_zones->ztree) { + new_z = auth_zone_find(ct->auth_zones, old_z->name, + old_z->namelen, old_z->dclass); + if(!new_z) { + /* The zone has been removed. */ + if(!fr_add_auth_zone_change(fr, old_z, NULL, 1, 0, + 0)) { + lock_rw_unlock(&env->auth_zones->lock); + lock_rw_unlock(&ct->auth_zones->lock); + return 0; + } + } + } + lock_rw_unlock(&env->auth_zones->lock); + + /* Find added zones by looping over new list and lookup in current. */ + RBTREE_FOR(new_z, struct auth_zone*, &ct->auth_zones->ztree) { + lock_rw_rdlock(&env->auth_zones->lock); + old_z = auth_zone_find(env->auth_zones, new_z->name, + new_z->namelen, new_z->dclass); + if(!old_z) { + /* The zone has been added. */ + lock_rw_unlock(&env->auth_zones->lock); + if(!fr_add_auth_zone_change(fr, NULL, new_z, 0, 1, + 0)) { + lock_rw_unlock(&ct->auth_zones->lock); + return 0; + } + } else { + uint32_t old_serial = 0, new_serial = 0; + int have_old = 0, have_new = 0; + struct auth_xfer* old_xfr, *new_xfr; + lock_rw_rdlock(&new_z->lock); + lock_rw_rdlock(&old_z->lock); + new_xfr = auth_xfer_find(ct->auth_zones, new_z->name, + new_z->namelen, new_z->dclass); + old_xfr = auth_xfer_find(env->auth_zones, old_z->name, + old_z->namelen, old_z->dclass); + if(new_xfr) { + lock_basic_lock(&new_xfr->lock); + } + if(old_xfr) { + lock_basic_lock(&old_xfr->lock); + } + lock_rw_unlock(&env->auth_zones->lock); + + /* Change in the auth zone can be detected. */ + /* A change in serial number means that auth_xfer + * has to be updated. */ + have_old = (auth_zone_get_serial(old_z, + &old_serial)!=0); + have_new = (auth_zone_get_serial(new_z, + &new_serial)!=0); + if(have_old != have_new || old_serial != new_serial + || !xfr_masters_equal(old_xfr, new_xfr)) { + /* The zone has been changed. */ + if(!fr_add_auth_zone_change(fr, old_z, new_z, + 0, 0, 1)) { + lock_rw_unlock(&old_z->lock); + lock_rw_unlock(&new_z->lock); + lock_rw_unlock(&ct->auth_zones->lock); + if(new_xfr) { + lock_basic_unlock(&new_xfr->lock); + } + if(old_xfr) { + lock_basic_unlock(&old_xfr->lock); + } + return 0; + } + } + + if(new_xfr) { + lock_basic_unlock(&new_xfr->lock); + } + if(old_xfr) { + lock_basic_unlock(&old_xfr->lock); + } + lock_rw_unlock(&old_z->lock); + lock_rw_unlock(&new_z->lock); + } + } + + lock_rw_unlock(&ct->auth_zones->lock); + return 1; +} + +/** fast reload thread, construct from config the new items */ +static int +fr_construct_from_config(struct fast_reload_thread* fr, + struct config_file* newcfg, struct fast_reload_construct* ct) +{ + int have_view_respip_cfg = 0; + + if(!(ct->views = views_create())) { + fr_construct_clear(ct); + return 0; + } + if(!views_apply_cfg(ct->views, newcfg)) { + fr_construct_clear(ct); + return 0; + } + if(fr_poll_for_quit(fr)) + return 1; + + if(!(ct->acl = acl_list_create())) { + fr_construct_clear(ct); + return 0; + } + if(!acl_list_apply_cfg(ct->acl, newcfg, ct->views)) { + fr_construct_clear(ct); + return 0; + } + if(fr_poll_for_quit(fr)) + return 1; + + if(!(ct->acl_interface = acl_list_create())) { + fr_construct_clear(ct); + return 0; + } + if(!ct_acl_interface_setup_ports(ct->acl_interface, + fr->worker->daemon)) { + fr_construct_clear(ct); + return 0; + } + if(!acl_interface_apply_cfg(ct->acl_interface, newcfg, ct->views)) { + fr_construct_clear(ct); + return 0; + } + if(fr_poll_for_quit(fr)) + return 1; + + if(!(ct->tcl = tcl_list_create())) { + fr_construct_clear(ct); + return 0; + } + if(!tcl_list_apply_cfg(ct->tcl, newcfg)) { + fr_construct_clear(ct); + return 0; + } + if(fr->worker->daemon->tcl->tree.count != 0) + fr->worker->daemon->fast_reload_tcl_has_changes = 1; + else fr->worker->daemon->fast_reload_tcl_has_changes = 0; + if(fr_poll_for_quit(fr)) + return 1; + + if(!(ct->auth_zones = auth_zones_create())) { + fr_construct_clear(ct); + return 0; + } + if(!auth_zones_apply_cfg(ct->auth_zones, newcfg, 1, &ct->use_rpz, + fr->worker->daemon->env, &fr->worker->daemon->mods)) { + fr_construct_clear(ct); + return 0; + } + if(!auth_zones_check_changes(fr, ct)) { + fr_construct_clear(ct); + return 0; + } + if(fr_poll_for_quit(fr)) + return 1; + + if(!(ct->fwds = forwards_create())) { + fr_construct_clear(ct); + return 0; + } + if(!forwards_apply_cfg(ct->fwds, newcfg)) { + fr_construct_clear(ct); + return 0; + } + if(fr_poll_for_quit(fr)) + return 1; + + if(!(ct->hints = hints_create())) { + fr_construct_clear(ct); + return 0; + } + if(!hints_apply_cfg(ct->hints, newcfg)) { + fr_construct_clear(ct); + return 0; + } + if(fr_poll_for_quit(fr)) + return 1; + + if(!(ct->local_zones = local_zones_create())) { + fr_construct_clear(ct); + return 0; + } + if(!local_zones_apply_cfg(ct->local_zones, newcfg)) { + fr_construct_clear(ct); + return 0; + } + if(fr_poll_for_quit(fr)) + return 1; + + if(!(ct->respip_set = respip_set_create())) { + fr_construct_clear(ct); + return 0; + } + if(!respip_global_apply_cfg(ct->respip_set, newcfg)) { + fr_construct_clear(ct); + return 0; + } + if(fr_poll_for_quit(fr)) + return 1; + if(!respip_views_apply_cfg(ct->views, newcfg, &have_view_respip_cfg)) { + fr_construct_clear(ct); + return 0; + } + ct->use_response_ip = !respip_set_is_empty(ct->respip_set) || + have_view_respip_cfg; + if(fr_poll_for_quit(fr)) + return 1; + + if(!(ct->edns_strings = edns_strings_create())) { + fr_construct_clear(ct); + return 0; + } + if(!edns_strings_apply_cfg(ct->edns_strings, newcfg)) { + fr_construct_clear(ct); + return 0; + } + if(fr_poll_for_quit(fr)) + return 1; + + if(fr->worker->env.anchors) { + /* There are trust anchors already, so create it for reload. */ + if(!(ct->anchors = anchors_create())) { + fr_construct_clear(ct); + return 0; + } + if(!anchors_apply_cfg(ct->anchors, newcfg)) { + fr_construct_clear(ct); + return 0; + } + if(fr_poll_for_quit(fr)) + return 1; + } + + if(!val_env_parse_key_iter(newcfg->val_nsec3_key_iterations, + &ct->nsec3_keysize, &ct->nsec3_maxiter, + &ct->nsec3_keyiter_count)) { + fr_construct_clear(ct); + return 0; + } + if(fr_poll_for_quit(fr)) + return 1; + + if(!read_fetch_policy(&ct->target_fetch_policy, + &ct->max_dependency_depth, newcfg->target_fetch_policy)) { + fr_construct_clear(ct); + return 0; + } + if(!(ct->donotq = donotq_create())) { + fr_construct_clear(ct); + return 0; + } + if(!donotq_apply_cfg(ct->donotq, newcfg)) { + fr_construct_clear(ct); + return 0; + } + if(!(ct->priv = priv_create())) { + fr_construct_clear(ct); + return 0; + } + if(!priv_apply_cfg(ct->priv, newcfg)) { + fr_construct_clear(ct); + return 0; + } + if(newcfg->caps_whitelist) { + if(!(ct->caps_white = caps_white_create())) { + fr_construct_clear(ct); + return 0; + } + if(!caps_white_apply_cfg(ct->caps_white, newcfg)) { + fr_construct_clear(ct); + return 0; + } + } + if(!nat64_apply_cfg(&ct->nat64, newcfg)) { + fr_construct_clear(ct); + return 0; + } + if(fr_poll_for_quit(fr)) + return 1; + + if(!setup_wait_limits(&ct->wait_limits_netblock, + &ct->wait_limits_cookie_netblock, newcfg)) { + fr_construct_clear(ct); + return 0; + } + if(!setup_domain_limits(&ct->domain_limits, newcfg)) { + fr_construct_clear(ct); + return 0; + } + if(fr_poll_for_quit(fr)) + return 1; + + if(!(ct->oldcfg = (struct config_file*)calloc(1, + sizeof(*ct->oldcfg)))) { + fr_construct_clear(ct); + log_err("out of memory"); + return 0; + } + if(fr->fr_verb >= 2) { + if(!fr_printmem(fr, newcfg, ct)) + return 0; + } + return 1; +} + +/** fast reload thread, finish timers */ +static int +fr_finish_time(struct fast_reload_thread* fr, struct timeval* time_start, + struct timeval* time_read, struct timeval* time_construct, + struct timeval* time_reload, struct timeval* time_end) +{ + struct timeval total, readtime, constructtime, reloadtime, deletetime; + if(gettimeofday(time_end, NULL) < 0) + log_err("gettimeofday: %s", strerror(errno)); + + timeval_subtract(&total, time_end, time_start); + timeval_subtract(&readtime, time_read, time_start); + timeval_subtract(&constructtime, time_construct, time_read); + timeval_subtract(&reloadtime, time_reload, time_construct); + timeval_subtract(&deletetime, time_end, time_reload); + if(!fr_output_printf(fr, "read disk %3d.%6.6ds\n", + (int)readtime.tv_sec, (int)readtime.tv_usec)) + return 0; + if(!fr_output_printf(fr, "construct %3d.%6.6ds\n", + (int)constructtime.tv_sec, (int)constructtime.tv_usec)) + return 0; + if(!fr_output_printf(fr, "reload %3d.%6.6ds\n", + (int)reloadtime.tv_sec, (int)reloadtime.tv_usec)) + return 0; + if(!fr_output_printf(fr, "deletes %3d.%6.6ds\n", + (int)deletetime.tv_sec, (int)deletetime.tv_usec)) + return 0; + if(!fr_output_printf(fr, "total time %3d.%6.6ds\n", (int)total.tv_sec, + (int)total.tv_usec)) + return 0; + fr_send_notification(fr, fast_reload_notification_printout); + return 1; +} + +/** Swap auth zone information */ +static void +auth_zones_swap(struct auth_zones* az, struct auth_zones* data) +{ + rbtree_type oldztree = az->ztree; + int old_have_downstream = az->have_downstream; + struct auth_zone* old_rpz_first = az->rpz_first; + + az->ztree = data->ztree; + data->ztree = oldztree; + + az->have_downstream = data->have_downstream; + data->have_downstream = old_have_downstream; + + /* Leave num_query_up and num_query_down, the statistics can + * remain counted. */ + + az->rpz_first = data->rpz_first; + data->rpz_first = old_rpz_first; + + /* The xtree is not swapped. This contains the auth_xfer elements + * that contain tasks in progress, like zone transfers. + * The unchanged zones can keep their tasks in the tree, and thus + * the xfer elements can continue to be their callbacks. */ +} + +#if defined(ATOMIC_POINTER_LOCK_FREE) && defined(HAVE_LINK_ATOMIC_STORE) +/** Fast reload thread, if atomics are available, copy the config items + * one by one with atomic store operations. */ +static void +fr_atomic_copy_cfg(struct config_file* oldcfg, struct config_file* cfg, + struct config_file* newcfg) +{ +#define COPY_VAR_int(var) oldcfg->var = cfg->var; atomic_store((_Atomic int*)&cfg->var, newcfg->var); newcfg->var = 0; +#define COPY_VAR_ptr(var) oldcfg->var = cfg->var; atomic_store((void* _Atomic*)&cfg->var, newcfg->var); newcfg->var = 0; +#define COPY_VAR_unsigned_int(var) oldcfg->var = cfg->var; atomic_store((_Atomic unsigned*)&cfg->var, newcfg->var); newcfg->var = 0; +#define COPY_VAR_size_t(var) oldcfg->var = cfg->var; atomic_store((_Atomic size_t*)&cfg->var, newcfg->var); newcfg->var = 0; +#define COPY_VAR_uint8_t(var) oldcfg->var = cfg->var; atomic_store((_Atomic uint8_t*)&cfg->var, newcfg->var); newcfg->var = 0; +#define COPY_VAR_uint16_t(var) oldcfg->var = cfg->var; atomic_store((_Atomic uint16_t*)&cfg->var, newcfg->var); newcfg->var = 0; +#define COPY_VAR_uint32_t(var) oldcfg->var = cfg->var; atomic_store((_Atomic uint32_t*)&cfg->var, newcfg->var); newcfg->var = 0; +#define COPY_VAR_int32_t(var) oldcfg->var = cfg->var; atomic_store((_Atomic int32_t*)&cfg->var, newcfg->var); newcfg->var = 0; + /* If config file items are missing from this list, they are + * not updated by fast-reload +p. */ + /* For missing items, the oldcfg item is not updated, still NULL, + * and the cfg stays the same. The newcfg item is untouched. + * The newcfg item is then deleted later. */ + /* Items that need synchronisation are omitted from the list. + * Use fast-reload without +p to update them together. */ + COPY_VAR_int(verbosity); + COPY_VAR_int(stat_interval); + COPY_VAR_int(stat_cumulative); + COPY_VAR_int(stat_extended); + COPY_VAR_int(stat_inhibit_zero); + COPY_VAR_int(num_threads); + COPY_VAR_int(port); + COPY_VAR_int(do_ip4); + COPY_VAR_int(do_ip6); + COPY_VAR_int(do_nat64); + COPY_VAR_int(prefer_ip4); + COPY_VAR_int(prefer_ip6); + COPY_VAR_int(do_udp); + COPY_VAR_int(do_tcp); + COPY_VAR_size_t(max_reuse_tcp_queries); + COPY_VAR_int(tcp_reuse_timeout); + COPY_VAR_int(tcp_auth_query_timeout); + COPY_VAR_int(tcp_upstream); + COPY_VAR_int(udp_upstream_without_downstream); + COPY_VAR_int(tcp_mss); + COPY_VAR_int(outgoing_tcp_mss); + COPY_VAR_int(tcp_idle_timeout); + COPY_VAR_int(do_tcp_keepalive); + COPY_VAR_int(tcp_keepalive_timeout); + COPY_VAR_int(sock_queue_timeout); + COPY_VAR_ptr(proxy_protocol_port); + COPY_VAR_ptr(ssl_service_key); + COPY_VAR_ptr(ssl_service_pem); + COPY_VAR_int(ssl_port); + COPY_VAR_int(ssl_upstream); + COPY_VAR_ptr(tls_cert_bundle); + COPY_VAR_int(tls_win_cert); + COPY_VAR_ptr(tls_additional_port); + /* The first is used to walk throught the list but last is + * only used during config read. */ + COPY_VAR_ptr(tls_session_ticket_keys.first); + COPY_VAR_ptr(tls_session_ticket_keys.last); + COPY_VAR_ptr(tls_ciphers); + COPY_VAR_ptr(tls_ciphersuites); + COPY_VAR_int(tls_use_sni); + COPY_VAR_int(https_port); + COPY_VAR_ptr(http_endpoint); + COPY_VAR_uint32_t(http_max_streams); + COPY_VAR_size_t(http_query_buffer_size); + COPY_VAR_size_t(http_response_buffer_size); + COPY_VAR_int(http_nodelay); + COPY_VAR_int(http_notls_downstream); + COPY_VAR_int(outgoing_num_ports); + COPY_VAR_size_t(outgoing_num_tcp); + COPY_VAR_size_t(incoming_num_tcp); + COPY_VAR_ptr(outgoing_avail_ports); + COPY_VAR_size_t(edns_buffer_size); + COPY_VAR_size_t(stream_wait_size); + COPY_VAR_size_t(msg_buffer_size); + COPY_VAR_size_t(msg_cache_size); + COPY_VAR_size_t(msg_cache_slabs); + COPY_VAR_size_t(num_queries_per_thread); + COPY_VAR_size_t(jostle_time); + COPY_VAR_size_t(rrset_cache_size); + COPY_VAR_size_t(rrset_cache_slabs); + COPY_VAR_int(host_ttl); + COPY_VAR_size_t(infra_cache_slabs); + COPY_VAR_size_t(infra_cache_numhosts); + COPY_VAR_int(infra_cache_min_rtt); + COPY_VAR_int(infra_cache_max_rtt); + COPY_VAR_int(infra_keep_probing); + COPY_VAR_int(delay_close); + COPY_VAR_int(udp_connect); + COPY_VAR_ptr(target_fetch_policy); + COPY_VAR_int(fast_server_permil); + COPY_VAR_size_t(fast_server_num); + COPY_VAR_int(if_automatic); + COPY_VAR_ptr(if_automatic_ports); + COPY_VAR_size_t(so_rcvbuf); + COPY_VAR_size_t(so_sndbuf); + COPY_VAR_int(so_reuseport); + COPY_VAR_int(ip_transparent); + COPY_VAR_int(ip_freebind); + COPY_VAR_int(ip_dscp); + /* Not copied because the length and items could then not match. + num_ifs, ifs, num_out_ifs, out_ifs + */ + COPY_VAR_ptr(root_hints); + COPY_VAR_ptr(stubs); + COPY_VAR_ptr(forwards); + COPY_VAR_ptr(auths); + COPY_VAR_ptr(views); + COPY_VAR_ptr(donotqueryaddrs); +#ifdef CLIENT_SUBNET + COPY_VAR_ptr(client_subnet); + COPY_VAR_ptr(client_subnet_zone); + COPY_VAR_uint16_t(client_subnet_opcode); + COPY_VAR_int(client_subnet_always_forward); + COPY_VAR_uint8_t(max_client_subnet_ipv4); + COPY_VAR_uint8_t(max_client_subnet_ipv6); + COPY_VAR_uint8_t(min_client_subnet_ipv4); + COPY_VAR_uint8_t(min_client_subnet_ipv6); + COPY_VAR_uint32_t(max_ecs_tree_size_ipv4); + COPY_VAR_uint32_t(max_ecs_tree_size_ipv6); +#endif + COPY_VAR_ptr(acls); + COPY_VAR_int(donotquery_localhost); + COPY_VAR_ptr(tcp_connection_limits); + COPY_VAR_int(harden_short_bufsize); + COPY_VAR_int(harden_large_queries); + COPY_VAR_int(harden_glue); + COPY_VAR_int(harden_dnssec_stripped); + COPY_VAR_int(harden_below_nxdomain); + COPY_VAR_int(harden_referral_path); + COPY_VAR_int(harden_algo_downgrade); + COPY_VAR_int(harden_unknown_additional); + COPY_VAR_int(use_caps_bits_for_id); + COPY_VAR_ptr(caps_whitelist); + COPY_VAR_ptr(private_address); + COPY_VAR_ptr(private_domain); + COPY_VAR_size_t(unwanted_threshold); + COPY_VAR_int(max_ttl); + COPY_VAR_int(min_ttl); + COPY_VAR_int(max_negative_ttl); + COPY_VAR_int(min_negative_ttl); + COPY_VAR_int(prefetch); + COPY_VAR_int(prefetch_key); + COPY_VAR_int(deny_any); + COPY_VAR_ptr(chrootdir); + COPY_VAR_ptr(username); + COPY_VAR_ptr(directory); + COPY_VAR_ptr(logfile); + COPY_VAR_ptr(pidfile); + COPY_VAR_int(use_syslog); + COPY_VAR_int(log_time_ascii); + COPY_VAR_int(log_queries); + COPY_VAR_int(log_replies); + COPY_VAR_int(log_tag_queryreply); + COPY_VAR_int(log_local_actions); + COPY_VAR_int(log_servfail); + COPY_VAR_ptr(log_identity); + COPY_VAR_int(log_destaddr); + COPY_VAR_int(hide_identity); + COPY_VAR_int(hide_version); + COPY_VAR_int(hide_trustanchor); + COPY_VAR_int(hide_http_user_agent); + COPY_VAR_ptr(identity); + COPY_VAR_ptr(version); + COPY_VAR_ptr(http_user_agent); + COPY_VAR_ptr(nsid_cfg_str); + /* Not copied because the length and items could then not match. + nsid; + nsid_len; + */ + COPY_VAR_ptr(module_conf); + COPY_VAR_ptr(trust_anchor_file_list); + COPY_VAR_ptr(trust_anchor_list); + COPY_VAR_ptr(auto_trust_anchor_file_list); + COPY_VAR_ptr(trusted_keys_file_list); + COPY_VAR_ptr(domain_insecure); + COPY_VAR_int(trust_anchor_signaling); + COPY_VAR_int(root_key_sentinel); + COPY_VAR_int32_t(val_date_override); + COPY_VAR_int32_t(val_sig_skew_min); + COPY_VAR_int32_t(val_sig_skew_max); + COPY_VAR_int32_t(val_max_restart); + COPY_VAR_int(bogus_ttl); + COPY_VAR_int(val_clean_additional); + COPY_VAR_int(val_log_level); + COPY_VAR_int(val_log_squelch); + COPY_VAR_int(val_permissive_mode); + COPY_VAR_int(aggressive_nsec); + COPY_VAR_int(ignore_cd); + COPY_VAR_int(disable_edns_do); + COPY_VAR_int(serve_expired); + COPY_VAR_int(serve_expired_ttl); + COPY_VAR_int(serve_expired_ttl_reset); + COPY_VAR_int(serve_expired_reply_ttl); + COPY_VAR_int(serve_expired_client_timeout); + COPY_VAR_int(ede_serve_expired); + COPY_VAR_int(dns_error_reporting); + COPY_VAR_int(serve_original_ttl); + COPY_VAR_ptr(val_nsec3_key_iterations); + COPY_VAR_int(zonemd_permissive_mode); + COPY_VAR_unsigned_int(add_holddown); + COPY_VAR_unsigned_int(del_holddown); + COPY_VAR_unsigned_int(keep_missing); + COPY_VAR_int(permit_small_holddown); + COPY_VAR_size_t(key_cache_size); + COPY_VAR_size_t(key_cache_slabs); + COPY_VAR_size_t(neg_cache_size); + COPY_VAR_ptr(local_zones); + COPY_VAR_ptr(local_zones_nodefault); +#ifdef USE_IPSET + COPY_VAR_ptr(local_zones_ipset); +#endif + COPY_VAR_int(local_zones_disable_default); + COPY_VAR_ptr(local_data); + COPY_VAR_ptr(local_zone_overrides); + COPY_VAR_int(unblock_lan_zones); + COPY_VAR_int(insecure_lan_zones); + /* These reference tags + COPY_VAR_ptr(local_zone_tags); + COPY_VAR_ptr(acl_tags); + COPY_VAR_ptr(acl_tag_actions); + COPY_VAR_ptr(acl_tag_datas); + */ + COPY_VAR_ptr(acl_view); + COPY_VAR_ptr(interface_actions); + /* These reference tags + COPY_VAR_ptr(interface_tags); + COPY_VAR_ptr(interface_tag_actions); + COPY_VAR_ptr(interface_tag_datas); + */ + COPY_VAR_ptr(interface_view); + /* This references tags + COPY_VAR_ptr(respip_tags); + */ + COPY_VAR_ptr(respip_actions); + COPY_VAR_ptr(respip_data); + /* Not copied because the length and items could then not match. + * also the respip module keeps a pointer to the array in its state. + tagname, num_tags + */ + COPY_VAR_int(remote_control_enable); + /* The first is used to walk throught the list but last is + * only used during config read. */ + COPY_VAR_ptr(control_ifs.first); + COPY_VAR_ptr(control_ifs.last); + COPY_VAR_int(control_use_cert); + COPY_VAR_int(control_port); + COPY_VAR_ptr(server_key_file); + COPY_VAR_ptr(server_cert_file); + COPY_VAR_ptr(control_key_file); + COPY_VAR_ptr(control_cert_file); + COPY_VAR_ptr(python_script); + COPY_VAR_ptr(dynlib_file); + COPY_VAR_int(use_systemd); + COPY_VAR_int(do_daemonize); + COPY_VAR_int(minimal_responses); + COPY_VAR_int(rrset_roundrobin); + COPY_VAR_int(unknown_server_time_limit); + COPY_VAR_int(discard_timeout); + COPY_VAR_int(wait_limit); + COPY_VAR_int(wait_limit_cookie); + COPY_VAR_ptr(wait_limit_netblock); + COPY_VAR_ptr(wait_limit_cookie_netblock); + COPY_VAR_size_t(max_udp_size); + COPY_VAR_ptr(dns64_prefix); + COPY_VAR_int(dns64_synthall); + COPY_VAR_ptr(dns64_ignore_aaaa); + COPY_VAR_ptr(nat64_prefix); + COPY_VAR_int(dnstap); + COPY_VAR_int(dnstap_bidirectional); + COPY_VAR_ptr(dnstap_socket_path); + COPY_VAR_ptr(dnstap_ip); + COPY_VAR_int(dnstap_tls); + COPY_VAR_ptr(dnstap_tls_server_name); + COPY_VAR_ptr(dnstap_tls_cert_bundle); + COPY_VAR_ptr(dnstap_tls_client_key_file); + COPY_VAR_ptr(dnstap_tls_client_cert_file); + COPY_VAR_int(dnstap_send_identity); + COPY_VAR_int(dnstap_send_version); + COPY_VAR_ptr(dnstap_identity); + COPY_VAR_ptr(dnstap_version); + COPY_VAR_int(dnstap_sample_rate); + COPY_VAR_int(dnstap_log_resolver_query_messages); + COPY_VAR_int(dnstap_log_resolver_response_messages); + COPY_VAR_int(dnstap_log_client_query_messages); + COPY_VAR_int(dnstap_log_client_response_messages); + COPY_VAR_int(dnstap_log_forwarder_query_messages); + COPY_VAR_int(dnstap_log_forwarder_response_messages); + COPY_VAR_int(disable_dnssec_lame_check); + COPY_VAR_int(ip_ratelimit); + COPY_VAR_int(ip_ratelimit_cookie); + COPY_VAR_size_t(ip_ratelimit_slabs); + COPY_VAR_size_t(ip_ratelimit_size); + COPY_VAR_int(ip_ratelimit_factor); + COPY_VAR_int(ip_ratelimit_backoff); + COPY_VAR_int(ratelimit); + COPY_VAR_size_t(ratelimit_slabs); + COPY_VAR_size_t(ratelimit_size); + COPY_VAR_ptr(ratelimit_for_domain); + COPY_VAR_ptr(ratelimit_below_domain); + COPY_VAR_int(ratelimit_factor); + COPY_VAR_int(ratelimit_backoff); + COPY_VAR_int(outbound_msg_retry); + COPY_VAR_int(max_sent_count); + COPY_VAR_int(max_query_restarts); + COPY_VAR_int(qname_minimisation); + COPY_VAR_int(qname_minimisation_strict); + COPY_VAR_int(shm_enable); + COPY_VAR_int(shm_key); + COPY_VAR_ptr(edns_client_strings); + COPY_VAR_uint16_t(edns_client_string_opcode); + COPY_VAR_int(dnscrypt); + COPY_VAR_int(dnscrypt_port); + COPY_VAR_ptr(dnscrypt_provider); + COPY_VAR_ptr(dnscrypt_secret_key); + COPY_VAR_ptr(dnscrypt_provider_cert); + COPY_VAR_ptr(dnscrypt_provider_cert_rotated); + COPY_VAR_size_t(dnscrypt_shared_secret_cache_size); + COPY_VAR_size_t(dnscrypt_shared_secret_cache_slabs); + COPY_VAR_size_t(dnscrypt_nonce_cache_size); + COPY_VAR_size_t(dnscrypt_nonce_cache_slabs); + COPY_VAR_int(pad_responses); + COPY_VAR_size_t(pad_responses_block_size); + COPY_VAR_int(pad_queries); + COPY_VAR_size_t(pad_queries_block_size); +#ifdef USE_IPSECMOD + COPY_VAR_int(ipsecmod_enabled); + COPY_VAR_ptr(ipsecmod_whitelist); + COPY_VAR_ptr(ipsecmod_hook); + COPY_VAR_int(ipsecmod_ignore_bogus); + COPY_VAR_int(ipsecmod_max_ttl); + COPY_VAR_int(ipsecmod_strict); +#endif +#ifdef USE_CACHEDB + COPY_VAR_ptr(cachedb_backend); + COPY_VAR_ptr(cachedb_secret); + COPY_VAR_int(cachedb_no_store); + COPY_VAR_int(cachedb_check_when_serve_expired); +#ifdef USE_REDIS + COPY_VAR_ptr(redis_server_host); + COPY_VAR_ptr(redis_replica_server_host); + COPY_VAR_int(redis_server_port); + COPY_VAR_int(redis_replica_server_port); + COPY_VAR_ptr(redis_server_path); + COPY_VAR_ptr(redis_replica_server_path); + COPY_VAR_ptr(redis_server_password); + COPY_VAR_ptr(redis_replica_server_password); + COPY_VAR_int(redis_timeout); + COPY_VAR_int(redis_replica_timeout); + COPY_VAR_int(redis_command_timeout); + COPY_VAR_int(redis_replica_command_timeout); + COPY_VAR_int(redis_connect_timeout); + COPY_VAR_int(redis_replica_connect_timeout); + COPY_VAR_int(redis_expire_records); + COPY_VAR_int(redis_logical_db); + COPY_VAR_int(redis_replica_logical_db); +#endif +#endif + COPY_VAR_int(do_answer_cookie); + /* Not copied because the length and content could then not match. + cookie_secret[40], cookie_secret_len + */ +#ifdef USE_IPSET + COPY_VAR_ptr(ipset_name_v4); + COPY_VAR_ptr(ipset_name_v6); +#endif + COPY_VAR_int(ede); +} +#endif /* ATOMIC_POINTER_LOCK_FREE && HAVE_LINK_ATOMIC_STORE */ + +/** fast reload thread, adjust the cache sizes */ +static void +fr_adjust_cache(struct module_env* env, struct config_file* oldcfg) +{ + if(env->cfg->msg_cache_size != oldcfg->msg_cache_size) + slabhash_adjust_size(env->msg_cache, env->cfg->msg_cache_size); + if(env->cfg->rrset_cache_size != oldcfg->rrset_cache_size) + slabhash_adjust_size(&env->rrset_cache->table, + env->cfg->rrset_cache_size); + if(env->key_cache && + env->cfg->key_cache_size != oldcfg->key_cache_size) + slabhash_adjust_size(env->key_cache->slab, + env->cfg->key_cache_size); + if(env->cfg->infra_cache_numhosts != oldcfg->infra_cache_numhosts) { + size_t inframem = env->cfg->infra_cache_numhosts * + (sizeof(struct infra_key) + sizeof(struct infra_data) + + INFRA_BYTES_NAME); + slabhash_adjust_size(env->infra_cache->hosts, inframem); + } + if(env->cfg->ratelimit_size != oldcfg->ratelimit_size) { + slabhash_adjust_size(env->infra_cache->domain_rates, + env->cfg->ratelimit_size); + slabhash_adjust_size(env->infra_cache->client_ip_rates, + env->cfg->ratelimit_size); + } + if(env->neg_cache && + env->cfg->neg_cache_size != oldcfg->neg_cache_size) { + val_neg_adjust_size(env->neg_cache, env->cfg->neg_cache_size); + } +} + +/** fast reload thread, adjust the iterator env */ +static void +fr_adjust_iter_env(struct module_env* env, struct fast_reload_construct* ct) +{ + int m; + struct iter_env* iter_env = NULL; + /* There is no comparison here to see if no options changed and thus + * no swap is needed, the trees with addresses and domains can be + * large and that would take too long. Instead the trees are + * swapped in. */ + + /* Because the iterator env is not locked, the update cannot happen + * when fr nopause is used. Without it the fast reload pauses the + * other threads, so they are not currently using the structure. */ + m = modstack_find(env->modstack, "iterator"); + if(m != -1) iter_env = (struct iter_env*)env->modinfo[m]; + if(iter_env) { + /* Swap the data so that the delete happens afterwards. */ + int* oldtargetfetchpolicy = iter_env->target_fetch_policy; + int oldmaxdependencydepth = iter_env->max_dependency_depth; + struct iter_donotq* olddonotq = iter_env->donotq; + struct iter_priv* oldpriv = iter_env->priv; + struct rbtree_type* oldcapswhite = iter_env->caps_white; + struct iter_nat64 oldnat64 = iter_env->nat64; + + iter_env->target_fetch_policy = ct->target_fetch_policy; + iter_env->max_dependency_depth = ct->max_dependency_depth; + iter_env->donotq = ct->donotq; + iter_env->priv = ct->priv; + iter_env->caps_white = ct->caps_white; + iter_env->nat64 = ct->nat64; + iter_env->outbound_msg_retry = env->cfg->outbound_msg_retry; + iter_env->max_sent_count = env->cfg->max_sent_count; + iter_env->max_query_restarts = env->cfg->max_query_restarts; + + ct->target_fetch_policy = oldtargetfetchpolicy; + ct->max_dependency_depth = oldmaxdependencydepth; + ct->donotq = olddonotq; + ct->priv = oldpriv; + ct->caps_white = oldcapswhite; + ct->nat64 = oldnat64; + } +} + +/** fast reload thread, adjust the validator env */ +static void +fr_adjust_val_env(struct module_env* env, struct fast_reload_construct* ct, + struct config_file* oldcfg) +{ + int m; + struct val_env* val_env = NULL; + if(env->cfg->bogus_ttl == oldcfg->bogus_ttl && + env->cfg->val_date_override == oldcfg->val_date_override && + env->cfg->val_sig_skew_min == oldcfg->val_sig_skew_min && + env->cfg->val_sig_skew_max == oldcfg->val_sig_skew_max && + env->cfg->val_max_restart == oldcfg->val_max_restart && + strcmp(env->cfg->val_nsec3_key_iterations, + oldcfg->val_nsec3_key_iterations) == 0) + return; /* no changes */ + + /* Because the validator env is not locked, the update cannot happen + * when fr nopause is used. Without it the fast reload pauses the + * other threads, so they are not currently using the structure. */ + m = modstack_find(env->modstack, "validator"); + if(m != -1) val_env = (struct val_env*)env->modinfo[m]; + if(val_env) { + /* Swap the arrays so that the delete happens afterwards. */ + size_t* oldkeysize = val_env->nsec3_keysize; + size_t* oldmaxiter = val_env->nsec3_maxiter; + val_env->nsec3_keysize = NULL; + val_env->nsec3_maxiter = NULL; + val_env_apply_cfg(val_env, env->cfg, ct->nsec3_keysize, + ct->nsec3_maxiter, ct->nsec3_keyiter_count); + ct->nsec3_keysize = oldkeysize; + ct->nsec3_maxiter = oldmaxiter; + if(env->neg_cache) { + lock_basic_lock(&env->neg_cache->lock); + env->neg_cache->nsec3_max_iter = val_env-> + nsec3_maxiter[val_env->nsec3_keyiter_count-1]; + lock_basic_unlock(&env->neg_cache->lock); + } + } +} + +/** fast reload thread, adjust the infra cache parameters */ +static void +fr_adjust_infra(struct module_env* env, struct fast_reload_construct* ct) +{ + struct infra_cache* infra = env->infra_cache; + struct config_file* cfg = env->cfg; + struct rbtree_type oldwaitlim = infra->wait_limits_netblock; + struct rbtree_type oldwaitlimcookie = + infra->wait_limits_cookie_netblock; + struct rbtree_type olddomainlim = infra->domain_limits; + + /* The size of the infra cache and ip rates is changed + * in fr_adjust_cache. */ + infra->host_ttl = cfg->host_ttl; + infra->infra_keep_probing = cfg->infra_keep_probing; + infra_dp_ratelimit = cfg->ratelimit; + infra_ip_ratelimit = cfg->ip_ratelimit; + infra_ip_ratelimit_cookie = cfg->ip_ratelimit_cookie; + infra->wait_limits_netblock = ct->wait_limits_netblock; + infra->wait_limits_cookie_netblock = ct->wait_limits_cookie_netblock; + infra->domain_limits = ct->domain_limits; + + ct->wait_limits_netblock = oldwaitlim; + ct->wait_limits_cookie_netblock = oldwaitlimcookie; + ct->domain_limits = olddomainlim; +} + +/** fast reload thread, reload config with putting the new config items + * in place and swapping out the old items. */ +static int +fr_reload_config(struct fast_reload_thread* fr, struct config_file* newcfg, + struct fast_reload_construct* ct) +{ + struct daemon* daemon = fr->worker->daemon; + struct module_env* env = daemon->env; + + /* These are constructed in the fr_construct_from_config routine. */ + log_assert(ct->oldcfg); + log_assert(ct->fwds); + log_assert(ct->hints); + + /* Grab big locks to satisfy lock conditions. */ + lock_rw_wrlock(&ct->views->lock); + lock_rw_wrlock(&env->views->lock); + lock_rw_wrlock(&ct->respip_set->lock); + lock_rw_wrlock(&env->respip_set->lock); + lock_rw_wrlock(&ct->local_zones->lock); + lock_rw_wrlock(&daemon->local_zones->lock); + lock_rw_wrlock(&ct->auth_zones->rpz_lock); + lock_rw_wrlock(&env->auth_zones->rpz_lock); + lock_rw_wrlock(&ct->auth_zones->lock); + lock_rw_wrlock(&env->auth_zones->lock); + lock_rw_wrlock(&ct->fwds->lock); + lock_rw_wrlock(&env->fwds->lock); + lock_rw_wrlock(&ct->hints->lock); + lock_rw_wrlock(&env->hints->lock); + if(ct->anchors) { + lock_basic_lock(&ct->anchors->lock); + lock_basic_lock(&env->anchors->lock); + } + +#if defined(ATOMIC_POINTER_LOCK_FREE) && defined(HAVE_LINK_ATOMIC_STORE) + if(fr->fr_nopause) { + fr_atomic_copy_cfg(ct->oldcfg, env->cfg, newcfg); + } else { +#endif + /* Store old config elements. */ + *ct->oldcfg = *env->cfg; + /* Insert new config elements. */ + *env->cfg = *newcfg; +#if defined(ATOMIC_POINTER_LOCK_FREE) && defined(HAVE_LINK_ATOMIC_STORE) + } +#endif + + if(env->cfg->log_identity || ct->oldcfg->log_identity) { + /* pick up new log_identity string to use for log output. */ + log_ident_set_or_default(env->cfg->log_identity); + } + /* the newcfg elements are in env->cfg, so should not be freed here. */ +#if defined(ATOMIC_POINTER_LOCK_FREE) && defined(HAVE_LINK_ATOMIC_STORE) + /* if used, the routine that copies the config has zeroed items. */ + if(!fr->fr_nopause) +#endif + memset(newcfg, 0, sizeof(*newcfg)); + + /* Quickly swap the tree roots themselves with the already allocated + * elements. This is a quick swap operation on the pointer. + * The other threads are stopped and locks are held, so that a + * consistent view of the configuration, before, and after, exists + * towards the state machine for query resolution. */ + forwards_swap_tree(env->fwds, ct->fwds); + hints_swap_tree(env->hints, ct->hints); + views_swap_tree(env->views, ct->views); + acl_list_swap_tree(daemon->acl, ct->acl); + acl_list_swap_tree(daemon->acl_interface, ct->acl_interface); + tcl_list_swap_tree(daemon->tcl, ct->tcl); + local_zones_swap_tree(daemon->local_zones, ct->local_zones); + respip_set_swap_tree(env->respip_set, ct->respip_set); + daemon->use_response_ip = ct->use_response_ip; + daemon->use_rpz = ct->use_rpz; + auth_zones_swap(env->auth_zones, ct->auth_zones); + edns_strings_swap_tree(env->edns_strings, ct->edns_strings); + anchors_swap_tree(env->anchors, ct->anchors); +#ifdef USE_CACHEDB + daemon->env->cachedb_enabled = cachedb_is_enabled(&daemon->mods, + daemon->env); +#endif +#ifdef USE_DNSTAP + if(env->cfg->dnstap) { + if(!fr->fr_nopause) + dt_apply_cfg(daemon->dtenv, env->cfg); + else dt_apply_logcfg(daemon->dtenv, env->cfg); + } +#endif + fr_adjust_cache(env, ct->oldcfg); + if(!fr->fr_nopause) { + fr_adjust_iter_env(env, ct); + fr_adjust_val_env(env, ct, ct->oldcfg); + fr_adjust_infra(env, ct); + } + + /* Set globals with new config. */ + config_apply(env->cfg); + + lock_rw_unlock(&ct->views->lock); + lock_rw_unlock(&env->views->lock); + lock_rw_unlock(&ct->respip_set->lock); + lock_rw_unlock(&env->respip_set->lock); + lock_rw_unlock(&ct->local_zones->lock); + lock_rw_unlock(&daemon->local_zones->lock); + lock_rw_unlock(&ct->auth_zones->lock); + lock_rw_unlock(&env->auth_zones->lock); + lock_rw_unlock(&ct->auth_zones->rpz_lock); + lock_rw_unlock(&env->auth_zones->rpz_lock); + lock_rw_unlock(&ct->fwds->lock); + lock_rw_unlock(&env->fwds->lock); + lock_rw_unlock(&ct->hints->lock); + lock_rw_unlock(&env->hints->lock); + if(ct->anchors) { + lock_basic_unlock(&ct->anchors->lock); + lock_basic_unlock(&env->anchors->lock); + } + + return 1; +} + +/** fast reload, poll for ack incoming. */ +static void +fr_poll_for_ack(struct fast_reload_thread* fr) +{ + int loopexit = 0, bcount = 0; + uint32_t cmd; + ssize_t ret; + + if(fr->need_to_quit) + return; + /* Is there data? */ + if(!sock_poll_timeout(fr->commpair[1], -1, 1, 0, NULL)) { + log_err("fr_poll_for_ack: poll failed"); + return; + } + + /* Read the data */ + while(1) { + if(++loopexit > IPC_LOOP_MAX) { + log_err("fr_poll_for_ack: recv loops %s", + sock_strerror(errno)); + return; + } + ret = recv(fr->commpair[1], ((char*)&cmd)+bcount, + sizeof(cmd)-bcount, 0); + if(ret == -1) { + if( +#ifndef USE_WINSOCK + errno == EINTR || errno == EAGAIN +# ifdef EWOULDBLOCK + || errno == EWOULDBLOCK +# endif +#else + WSAGetLastError() == WSAEINTR || + WSAGetLastError() == WSAEINPROGRESS || + WSAGetLastError() == WSAEWOULDBLOCK +#endif + ) + continue; /* Try again. */ + log_err("fr_poll_for_ack: recv: %s", + sock_strerror(errno)); + return; + } else if(ret+(ssize_t)bcount != sizeof(cmd)) { + bcount += ret; + if((size_t)bcount < sizeof(cmd)) + continue; + } + break; + } + if(cmd == fast_reload_notification_exit) { + fr->need_to_quit = 1; + verbose(VERB_ALGO, "fast reload wait for ack: " + "exit notification received"); + return; + } + if(cmd != fast_reload_notification_reload_ack) { + verbose(VERB_ALGO, "fast reload wait for ack: " + "wrong notification %d", (int)cmd); + } +} + +/** fast reload thread, reload ipc communication to stop and start threads. */ +static int +fr_reload_ipc(struct fast_reload_thread* fr, struct config_file* newcfg, + struct fast_reload_construct* ct) +{ + int result = 1; + if(!fr->fr_nopause) { + fr_send_notification(fr, fast_reload_notification_reload_stop); + fr_poll_for_ack(fr); + } + if(!fr_reload_config(fr, newcfg, ct)) { + result = 0; + } + if(!fr->fr_nopause) { + fr_send_notification(fr, fast_reload_notification_reload_start); + fr_poll_for_ack(fr); + } + return result; +} + +/** fast reload thread, load config */ +static int +fr_load_config(struct fast_reload_thread* fr, struct timeval* time_read, + struct timeval* time_construct, struct timeval* time_reload) +{ + struct fast_reload_construct ct; + struct config_file* newcfg = NULL; + memset(&ct, 0, sizeof(ct)); + + /* Read file. */ + if(!fr_read_config(fr, &newcfg)) + return 0; + if(gettimeofday(time_read, NULL) < 0) + log_err("gettimeofday: %s", strerror(errno)); + if(fr_poll_for_quit(fr)) { + config_delete(newcfg); + return 1; + } + + /* Check if the config can be loaded */ + if(!fr_check_tag_defines(fr, newcfg)) { + config_delete(newcfg); + return 0; + } + if(!fr_check_compat_cfg(fr, newcfg)) { + config_delete(newcfg); + return 0; + } + if(!fr_check_nopause_cfg(fr, newcfg)) { + config_delete(newcfg); + return 0; + } + if(fr_poll_for_quit(fr)) { + config_delete(newcfg); + return 1; + } + + /* Construct items. */ + if(!fr_construct_from_config(fr, newcfg, &ct)) { + config_delete(newcfg); + if(!fr_output_printf(fr, "Could not construct from the " + "config, check for errors with unbound-checkconf, or " + "out of memory. The parse errors are printed in " + "the log.\n")) + return 0; + fr_send_notification(fr, fast_reload_notification_printout); + return 0; + } + if(gettimeofday(time_construct, NULL) < 0) + log_err("gettimeofday: %s", strerror(errno)); + if(fr_poll_for_quit(fr)) { + config_delete(newcfg); + fr_construct_clear(&ct); + return 1; + } + + /* Reload server. */ + if(!fr_reload_ipc(fr, newcfg, &ct)) { + config_delete(newcfg); + fr_construct_clear(&ct); + if(!fr_output_printf(fr, "error: reload failed\n")) + return 0; + fr_send_notification(fr, fast_reload_notification_printout); + return 0; + } + if(gettimeofday(time_reload, NULL) < 0) + log_err("gettimeofday: %s", strerror(errno)); + + if(fr_poll_for_quit(fr)) { + config_delete(newcfg); + fr_construct_clear(&ct); + return 1; + } + if(fr->fr_nopause) { + /* Poll every thread, with a no-work poll item over the + * command pipe. This makes the worker thread surely move + * to deal with that event, and thus the thread is no longer + * holding, eg. a string item from the old config struct. + * And then the old config struct can safely be deleted. + * Only needed when nopause is used, because without that + * the worker threads are already waiting on a command pipe + * item. This nopause command pipe item does not take work, + * it returns immediately, so it does not delay the workers. + * They can be polled one at a time. But its processing causes + * the worker to have released data items from old config. + * This also makes sure the threads are not holding locks on + * individual items in the local_zones, views, respip_set. */ + fr_send_notification(fr, + fast_reload_notification_reload_nopause_poll); + fr_poll_for_ack(fr); + } + + /* Delete old. */ + config_delete(newcfg); + fr_construct_clear(&ct); + return 1; +} + +/** fast reload thread. the thread main function */ +static void* fast_reload_thread_main(void* arg) +{ + struct fast_reload_thread* fast_reload_thread = (struct fast_reload_thread*)arg; + struct timeval time_start, time_read, time_construct, time_reload, + time_end; + log_thread_set(&fast_reload_thread->threadnum); + + verbose(VERB_ALGO, "start fast reload thread"); + if(fast_reload_thread->fr_verb >= 1) { + fr_init_time(&time_start, &time_read, &time_construct, + &time_reload, &time_end); + if(fr_poll_for_quit(fast_reload_thread)) + goto done; + } + + /* print output to the client */ + if(fast_reload_thread->fr_verb >= 1) { + if(!fr_output_printf(fast_reload_thread, "thread started\n")) + goto done_error; + fr_send_notification(fast_reload_thread, + fast_reload_notification_printout); + if(fr_poll_for_quit(fast_reload_thread)) + goto done; + } + + if(!fr_load_config(fast_reload_thread, &time_read, &time_construct, + &time_reload)) + goto done_error; + if(fr_poll_for_quit(fast_reload_thread)) + goto done; + + if(fast_reload_thread->fr_verb >= 1) { + if(!fr_finish_time(fast_reload_thread, &time_start, &time_read, + &time_construct, &time_reload, &time_end)) + goto done_error; + if(fr_poll_for_quit(fast_reload_thread)) + goto done; + } + + if(!fr_output_printf(fast_reload_thread, "ok\n")) + goto done_error; + fr_send_notification(fast_reload_thread, + fast_reload_notification_printout); + verbose(VERB_ALGO, "stop fast reload thread"); + /* If this is not an exit due to quit earlier, send regular done. */ + if(!fast_reload_thread->need_to_quit) + fr_send_notification(fast_reload_thread, + fast_reload_notification_done); + /* If during the fast_reload_notification_done send, + * fast_reload_notification_exit was received, ack it. If the + * thread is exiting due to quit received earlier, also ack it.*/ +done: + if(fast_reload_thread->need_to_quit) + fr_send_notification(fast_reload_thread, + fast_reload_notification_exited); + return NULL; +done_error: + verbose(VERB_ALGO, "stop fast reload thread with done_error"); + fr_send_notification(fast_reload_thread, + fast_reload_notification_done_error); + return NULL; +} +#endif /* !THREADS_DISABLED */ + +/** create a socketpair for bidirectional communication, false on failure */ +static int +create_socketpair(int* pair, struct ub_randstate* rand) +{ +#ifndef USE_WINSOCK + if(socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) { + log_err("socketpair: %s", strerror(errno)); + return 0; + } + (void)rand; +#else + struct sockaddr_in addr, baddr, accaddr, connaddr; + socklen_t baddrlen, accaddrlen, connaddrlen; + uint8_t localhost[] = {127, 0, 0, 1}; + uint8_t nonce[16], recvnonce[16]; + size_t i; + int lst, pollin_event, bcount, loopcount; + int connect_poll_timeout = 200; /* msec to wait for connection */ + ssize_t ret; + pair[0] = -1; + pair[1] = -1; + for(i=0; i<sizeof(nonce); i++) { + nonce[i] = ub_random_max(rand, 256); + } + lst = socket(AF_INET, SOCK_STREAM, 0); + if(lst == -1) { + log_err("create_socketpair: socket: %s", sock_strerror(errno)); + return 0; + } + memset(&addr, 0, sizeof(addr)); + addr.sin_family = AF_INET; + addr.sin_port = 0; + memcpy(&addr.sin_addr, localhost, 4); + if(bind(lst, (struct sockaddr*)&addr, (socklen_t)sizeof(addr)) + == -1) { + log_err("create socketpair: bind: %s", sock_strerror(errno)); + sock_close(lst); + return 0; + } + if(listen(lst, 12) == -1) { + log_err("create socketpair: listen: %s", sock_strerror(errno)); + sock_close(lst); + return 0; + } + + pair[1] = socket(AF_INET, SOCK_STREAM, 0); + if(pair[1] == -1) { + log_err("create socketpair: socket: %s", sock_strerror(errno)); + sock_close(lst); + return 0; + } + baddrlen = (socklen_t)sizeof(baddr); + if(getsockname(lst, (struct sockaddr*)&baddr, &baddrlen) == -1) { + log_err("create socketpair: getsockname: %s", + sock_strerror(errno)); + sock_close(lst); + sock_close(pair[1]); + pair[1] = -1; + return 0; + } + if(baddrlen > (socklen_t)sizeof(baddr)) { + log_err("create socketpair: getsockname returned addr too big"); + sock_close(lst); + sock_close(pair[1]); + pair[1] = -1; + return 0; + } + /* the socket is blocking */ + if(connect(pair[1], (struct sockaddr*)&baddr, baddrlen) == -1) { + log_err("create socketpair: connect: %s", + sock_strerror(errno)); + sock_close(lst); + sock_close(pair[1]); + pair[1] = -1; + return 0; + } + if(!sock_poll_timeout(lst, connect_poll_timeout, 1, 0, &pollin_event)) { + log_err("create socketpair: poll for accept failed: %s", + sock_strerror(errno)); + sock_close(lst); + sock_close(pair[1]); + pair[1] = -1; + return 0; + } + if(!pollin_event) { + log_err("create socketpair: poll timeout for accept"); + sock_close(lst); + sock_close(pair[1]); + pair[1] = -1; + return 0; + } + accaddrlen = (socklen_t)sizeof(accaddr); + pair[0] = accept(lst, (struct sockaddr*)&accaddr, &accaddrlen); + if(pair[0] == -1) { + log_err("create socketpair: accept: %s", sock_strerror(errno)); + sock_close(lst); + sock_close(pair[1]); + pair[1] = -1; + return 0; + } + if(accaddrlen > (socklen_t)sizeof(accaddr)) { + log_err("create socketpair: accept returned addr too big"); + sock_close(lst); + sock_close(pair[0]); + sock_close(pair[1]); + pair[0] = -1; + pair[1] = -1; + return 0; + } + if(accaddr.sin_family != AF_INET || + memcmp(localhost, &accaddr.sin_addr, 4) != 0) { + log_err("create socketpair: accept from wrong address"); + sock_close(lst); + sock_close(pair[0]); + sock_close(pair[1]); + pair[0] = -1; + pair[1] = -1; + return 0; + } + connaddrlen = (socklen_t)sizeof(connaddr); + if(getsockname(pair[1], (struct sockaddr*)&connaddr, &connaddrlen) + == -1) { + log_err("create socketpair: getsockname connectedaddr: %s", + sock_strerror(errno)); + sock_close(lst); + sock_close(pair[0]); + sock_close(pair[1]); + pair[0] = -1; + pair[1] = -1; + return 0; + } + if(connaddrlen > (socklen_t)sizeof(connaddr)) { + log_err("create socketpair: getsockname connectedaddr returned addr too big"); + sock_close(lst); + sock_close(pair[0]); + sock_close(pair[1]); + pair[0] = -1; + pair[1] = -1; + return 0; + } + if(connaddr.sin_family != AF_INET || + memcmp(localhost, &connaddr.sin_addr, 4) != 0) { + log_err("create socketpair: getsockname connectedaddr returned wrong address"); + sock_close(lst); + sock_close(pair[0]); + sock_close(pair[1]); + pair[0] = -1; + pair[1] = -1; + return 0; + } + if(accaddr.sin_port != connaddr.sin_port) { + log_err("create socketpair: accept from wrong port"); + sock_close(lst); + sock_close(pair[0]); + sock_close(pair[1]); + pair[0] = -1; + pair[1] = -1; + return 0; + } + sock_close(lst); + + loopcount = 0; + bcount = 0; + while(1) { + if(++loopcount > IPC_LOOP_MAX) { + log_err("create socketpair: send failed due to loop"); + sock_close(pair[0]); + sock_close(pair[1]); + pair[0] = -1; + pair[1] = -1; + return 0; + } + ret = send(pair[1], (void*)(nonce+bcount), + sizeof(nonce)-bcount, 0); + if(ret == -1) { + if( +#ifndef USE_WINSOCK + errno == EINTR || errno == EAGAIN +# ifdef EWOULDBLOCK + || errno == EWOULDBLOCK +# endif +#else + WSAGetLastError() == WSAEINTR || + WSAGetLastError() == WSAEINPROGRESS || + WSAGetLastError() == WSAEWOULDBLOCK +#endif + ) + continue; /* Try again. */ + log_err("create socketpair: send: %s", sock_strerror(errno)); + sock_close(pair[0]); + sock_close(pair[1]); + pair[0] = -1; + pair[1] = -1; + return 0; + } else if(ret+(ssize_t)bcount != sizeof(nonce)) { + bcount += ret; + if((size_t)bcount < sizeof(nonce)) + continue; + } + break; + } + + if(!sock_poll_timeout(pair[0], connect_poll_timeout, 1, 0, &pollin_event)) { + log_err("create socketpair: poll failed: %s", + sock_strerror(errno)); + sock_close(pair[0]); + sock_close(pair[1]); + pair[0] = -1; + pair[1] = -1; + return 0; + } + if(!pollin_event) { + log_err("create socketpair: poll timeout for recv"); + sock_close(pair[0]); + sock_close(pair[1]); + pair[0] = -1; + pair[1] = -1; + return 0; + } + + loopcount = 0; + bcount = 0; + while(1) { + if(++loopcount > IPC_LOOP_MAX) { + log_err("create socketpair: recv failed due to loop"); + sock_close(pair[0]); + sock_close(pair[1]); + pair[0] = -1; + pair[1] = -1; + return 0; + } + ret = recv(pair[0], (void*)(recvnonce+bcount), + sizeof(nonce)-bcount, 0); + if(ret == -1) { + if( +#ifndef USE_WINSOCK + errno == EINTR || errno == EAGAIN +# ifdef EWOULDBLOCK + || errno == EWOULDBLOCK +# endif +#else + WSAGetLastError() == WSAEINTR || + WSAGetLastError() == WSAEINPROGRESS || + WSAGetLastError() == WSAEWOULDBLOCK +#endif + ) + continue; /* Try again. */ + log_err("create socketpair: recv: %s", sock_strerror(errno)); + sock_close(pair[0]); + sock_close(pair[1]); + pair[0] = -1; + pair[1] = -1; + return 0; + } else if(ret == 0) { + log_err("create socketpair: stream closed"); + sock_close(pair[0]); + sock_close(pair[1]); + pair[0] = -1; + pair[1] = -1; + return 0; + } else if(ret+(ssize_t)bcount != sizeof(nonce)) { + bcount += ret; + if((size_t)bcount < sizeof(nonce)) + continue; + } + break; + } + + if(memcmp(nonce, recvnonce, sizeof(nonce)) != 0) { + log_err("create socketpair: recv wrong nonce"); + sock_close(pair[0]); + sock_close(pair[1]); + pair[0] = -1; + pair[1] = -1; + return 0; + } +#endif + return 1; +} + +/** fast reload thread. setup the thread info */ +static int +fast_reload_thread_setup(struct worker* worker, int fr_verb, int fr_nopause, + int fr_drop_mesh) +{ + struct fast_reload_thread* fr; + int numworkers = worker->daemon->num; + worker->daemon->fast_reload_thread = (struct fast_reload_thread*) + calloc(1, sizeof(*worker->daemon->fast_reload_thread)); + if(!worker->daemon->fast_reload_thread) + return 0; + fr = worker->daemon->fast_reload_thread; + fr->fr_verb = fr_verb; + fr->fr_nopause = fr_nopause; + fr->fr_drop_mesh = fr_drop_mesh; + worker->daemon->fast_reload_drop_mesh = fr->fr_drop_mesh; + /* The thread id printed in logs, numworker+1 is the dnstap thread. + * This is numworkers+2. */ + fr->threadnum = numworkers+2; + fr->commpair[0] = -1; + fr->commpair[1] = -1; + fr->commreload[0] = -1; + fr->commreload[1] = -1; + if(!create_socketpair(fr->commpair, worker->daemon->rand)) { + free(fr); + worker->daemon->fast_reload_thread = NULL; + return 0; + } + fr->worker = worker; + fr->fr_output = (struct config_strlist_head*)calloc(1, + sizeof(*fr->fr_output)); + if(!fr->fr_output) { + sock_close(fr->commpair[0]); + sock_close(fr->commpair[1]); + free(fr); + worker->daemon->fast_reload_thread = NULL; + return 0; + } + if(!create_socketpair(fr->commreload, worker->daemon->rand)) { + sock_close(fr->commpair[0]); + sock_close(fr->commpair[1]); + free(fr->fr_output); + free(fr); + worker->daemon->fast_reload_thread = NULL; + return 0; + } + lock_basic_init(&fr->fr_output_lock); + lock_protect(&fr->fr_output_lock, fr->fr_output, + sizeof(*fr->fr_output)); + return 1; +} + +/** fast reload, delete auth zone change list */ +static void +fr_auth_change_list_delete( + struct fast_reload_auth_change* auth_zone_change_list) +{ + struct fast_reload_auth_change* item, *next; + item = auth_zone_change_list; + while(item) { + next = item->next; + free(item); + item = next; + } +} + +/** fast reload thread. desetup and delete the thread info. */ +static void +fast_reload_thread_desetup(struct fast_reload_thread* fast_reload_thread) +{ + if(!fast_reload_thread) + return; + if(fast_reload_thread->service_event && + fast_reload_thread->service_event_is_added) { + ub_event_del(fast_reload_thread->service_event); + fast_reload_thread->service_event_is_added = 0; + } + if(fast_reload_thread->service_event) + ub_event_free(fast_reload_thread->service_event); + sock_close(fast_reload_thread->commpair[0]); + sock_close(fast_reload_thread->commpair[1]); + sock_close(fast_reload_thread->commreload[0]); + sock_close(fast_reload_thread->commreload[1]); + if(fast_reload_thread->printq) { + fr_main_perform_printout(fast_reload_thread); + /* If it is empty now, there is nothing to print on fd. */ + if(fr_printq_empty(fast_reload_thread->printq)) { + fr_printq_delete(fast_reload_thread->printq); + } else { + /* Keep the printq around to printout the remaining + * text to the remote client. Until it is done, it + * sits on a list, that is in the daemon struct. + * The event can then spool the remaining text to the + * remote client and eventually delete itself from the + * callback. */ + fr_printq_list_insert(fast_reload_thread->printq, + fast_reload_thread->worker->daemon); + fast_reload_thread->printq = NULL; + } + } + lock_basic_destroy(&fast_reload_thread->fr_output_lock); + if(fast_reload_thread->fr_output) { + config_delstrlist(fast_reload_thread->fr_output->first); + free(fast_reload_thread->fr_output); + } + fr_auth_change_list_delete(fast_reload_thread->auth_zone_change_list); + + free(fast_reload_thread); +} + +/** + * Fast reload thread, send a command to the thread. Blocking on timeout. + * It handles received input from the thread, if any is received. + */ +static void +fr_send_cmd_to(struct fast_reload_thread* fr, + enum fast_reload_notification status, int check_cmds, int blocking) +{ + int outevent, loopexit = 0, bcount = 0; + uint32_t cmd; + ssize_t ret; + verbose(VERB_ALGO, "send notification to fast reload thread: %s", + fr_notification_to_string(status)); + cmd = status; + while(1) { + if(++loopexit > IPC_LOOP_MAX) { + log_err("send notification to fast reload: could not send notification: loop"); + return; + } + if(check_cmds) + fr_check_cmd_from_thread(fr); + /* wait for socket to become writable */ + if(!sock_poll_timeout(fr->commpair[0], + (blocking?-1:IPC_NOTIFICATION_WAIT), + 0, 1, &outevent)) { + log_err("send notification to fast reload: poll failed"); + return; + } + if(!outevent) + continue; + /* keep static analyzer happy; send(-1,..) */ + log_assert(fr->commpair[0] >= 0); + ret = send(fr->commpair[0], ((char*)&cmd)+bcount, + sizeof(cmd)-bcount, 0); + if(ret == -1) { + if( +#ifndef USE_WINSOCK + errno == EINTR || errno == EAGAIN +# ifdef EWOULDBLOCK + || errno == EWOULDBLOCK +# endif +#else + WSAGetLastError() == WSAEINTR || + WSAGetLastError() == WSAEINPROGRESS || + WSAGetLastError() == WSAEWOULDBLOCK +#endif + ) + continue; /* Try again. */ + log_err("send notification to fast reload: send: %s", + sock_strerror(errno)); + return; + } else if(ret+(ssize_t)bcount != sizeof(cmd)) { + bcount += ret; + if((size_t)bcount < sizeof(cmd)) + continue; + } + break; + } +} + +/** Fast reload, the main thread handles that the fast reload thread has + * exited. */ +static void +fr_main_perform_done(struct fast_reload_thread* fr) +{ + struct worker* worker = fr->worker; + verbose(VERB_ALGO, "join with fastreload thread"); + ub_thread_join(fr->tid); + verbose(VERB_ALGO, "joined with fastreload thread"); + fast_reload_thread_desetup(fr); + worker->daemon->fast_reload_thread = NULL; +} + +/** Append strlist after strlist */ +static void +cfg_strlist_append_listhead(struct config_strlist_head* list, + struct config_strlist_head* more) +{ + if(!more->first) + return; + if(list->last) + list->last->next = more->first; + else + list->first = more->first; + list->last = more->last; +} + +/** Fast reload, the remote control thread handles that the fast reload thread + * has output to be printed, on the linked list that is locked. */ +static void +fr_main_perform_printout(struct fast_reload_thread* fr) +{ + struct config_strlist_head out; + + /* Fetch the list of items to be printed */ + lock_basic_lock(&fr->fr_output_lock); + out.first = fr->fr_output->first; + out.last = fr->fr_output->last; + fr->fr_output->first = NULL; + fr->fr_output->last = NULL; + lock_basic_unlock(&fr->fr_output_lock); + + if(!fr->printq || !fr->printq->client_cp) { + /* There is no output socket, delete it. */ + config_delstrlist(out.first); + return; + } + + /* Put them on the output list, not locked because the list + * producer and consumer are both owned by the remote control thread, + * it moves the items to the list for printing in the event callback + * for the client_cp. */ + cfg_strlist_append_listhead(fr->printq->to_print, &out); + + /* Set the client_cp to output if not already */ + if(!fr->printq->client_cp->event_added) + comm_point_listen_for_rw(fr->printq->client_cp, 0, 1); +} + +/** fast reload, receive ack from workers that they are waiting, run + * by the mainthr after sending them reload_stop. */ +static void +fr_read_ack_from_workers(struct fast_reload_thread* fr) +{ + struct daemon* daemon = fr->worker->daemon; + /* Every worker sends one byte, wait for num-1 bytes. */ + int count=0, total=daemon->num-1; + while(count < total) { + uint8_t r; + ssize_t ret; + ret = recv(fr->commreload[0], (void*)&r, 1, 0); + if(ret == -1) { + if( +#ifndef USE_WINSOCK + errno == EINTR || errno == EAGAIN +# ifdef EWOULDBLOCK + || errno == EWOULDBLOCK +# endif +#else + WSAGetLastError() == WSAEINTR || + WSAGetLastError() == WSAEINPROGRESS || + WSAGetLastError() == WSAEWOULDBLOCK +#endif + ) + continue; /* Try again */ + log_err("worker reload ack: recv failed: %s", + sock_strerror(errno)); + return; + } + count++; + verbose(VERB_ALGO, "worker reload ack from (uint8_t)%d", + (int)r); + } +} + +/** fast reload, poll for reload_start in mainthr waiting on a notification + * from the fast reload thread. */ +static void +fr_poll_for_reload_start(struct fast_reload_thread* fr) +{ + int loopexit = 0, bcount = 0; + uint32_t cmd; + ssize_t ret; + + /* Is there data? */ + if(!sock_poll_timeout(fr->commpair[0], -1, 1, 0, NULL)) { + log_err("fr_poll_for_reload_start: poll failed"); + return; + } + + /* Read the data */ + while(1) { + if(++loopexit > IPC_LOOP_MAX) { + log_err("fr_poll_for_reload_start: recv loops %s", + sock_strerror(errno)); + return; + } + ret = recv(fr->commpair[0], ((char*)&cmd)+bcount, + sizeof(cmd)-bcount, 0); + if(ret == -1) { + if( +#ifndef USE_WINSOCK + errno == EINTR || errno == EAGAIN +# ifdef EWOULDBLOCK + || errno == EWOULDBLOCK +# endif +#else + WSAGetLastError() == WSAEINTR || + WSAGetLastError() == WSAEINPROGRESS || + WSAGetLastError() == WSAEWOULDBLOCK +#endif + ) + continue; /* Try again. */ + log_err("fr_poll_for_reload_start: recv: %s", + sock_strerror(errno)); + return; + } else if(ret+(ssize_t)bcount != sizeof(cmd)) { + bcount += ret; + if((size_t)bcount < sizeof(cmd)) + continue; + } + break; + } + if(cmd != fast_reload_notification_reload_start) { + verbose(VERB_ALGO, "fast reload wait for ack: " + "wrong notification %d", (int)cmd); + } +} + +/** Pick up the worker mesh changes, after fast reload. */ +static void +fr_worker_pickup_mesh(struct worker* worker) +{ + struct mesh_area* mesh = worker->env.mesh; + struct config_file* cfg = worker->env.cfg; + mesh->use_response_ip = worker->daemon->use_response_ip; + mesh->use_rpz = worker->daemon->use_rpz; + mesh->max_reply_states = cfg->num_queries_per_thread; + mesh->max_forever_states = (mesh->max_reply_states+1)/2; +#ifndef S_SPLINT_S + mesh->jostle_max.tv_sec = (time_t)(cfg->jostle_time / 1000); + mesh->jostle_max.tv_usec = (time_t)((cfg->jostle_time % 1000)*1000); +#endif +} + +/** + * Remove the old tcl_addr entries from the open connections. + * They are only incremented when an accept is performed on a tcp comm point. + * @param front: listening comm ports of the worker. + */ +static void +tcl_remove_old(struct listen_dnsport* front) +{ + struct listen_list* l; + l = front->cps; + while(l) { + if(l->com->type == comm_tcp_accept) { + int i; + for(i=0; i<l->com->max_tcp_count; i++) { + if(l->com->tcp_handlers[i]->tcl_addr) { + /* Because the increment of the + * connection limit was in the old + * tcl list, the new list does not + * need a decrement. With NULL it is + * not decremented when the connection + * is done, and also there is no + * reference to the old connection + * limit structure. */ + l->com->tcp_handlers[i]->tcl_addr = + NULL; + } + } + } + l = l->next; + } +} + +/** Stop zonemd lookup */ +static void +auth_zone_zonemd_stop_lookup(struct auth_zone* z, struct mesh_area* mesh) +{ + struct query_info qinfo; + uint16_t qflags = BIT_RD; + qinfo.qname_len = z->namelen; + qinfo.qname = z->name; + qinfo.qclass = z->dclass; + qinfo.qtype = z->zonemd_callback_qtype; + qinfo.local_alias = NULL; + + mesh_remove_callback(mesh, &qinfo, qflags, + &auth_zonemd_dnskey_lookup_callback, z); +} + +/** Pick up the auth zone locks. */ +static void +fr_pickup_auth_locks(struct worker* worker, struct auth_zone* namez, + struct auth_zone* old_z, struct auth_zone* new_z, + struct auth_xfer** xfr, struct auth_xfer** loadxfr) +{ + uint8_t nm[LDNS_MAX_DOMAINLEN+1]; + size_t nmlen; + uint16_t dclass; + + log_assert(namez->namelen <= sizeof(nm)); + lock_rw_rdlock(&namez->lock); + nmlen = namez->namelen; + dclass = namez->dclass; + memmove(nm, namez->name, nmlen); + lock_rw_unlock(&namez->lock); + + lock_rw_wrlock(&worker->daemon->fast_reload_thread->old_auth_zones->lock); + lock_rw_wrlock(&worker->env.auth_zones->lock); + if(new_z) { + lock_rw_wrlock(&new_z->lock); + } + if(old_z) { + lock_rw_wrlock(&old_z->lock); + } + if(loadxfr) + *loadxfr = auth_xfer_find(worker->daemon->fast_reload_thread-> + old_auth_zones, nm, nmlen, dclass); + if(xfr) + *xfr = auth_xfer_find(worker->env.auth_zones, nm, nmlen, + dclass); + if(loadxfr && *loadxfr) { + lock_basic_lock(&(*loadxfr)->lock); + } + if(xfr && *xfr) { + lock_basic_lock(&(*xfr)->lock); + } +} + +/** Fast reload, worker picks up deleted auth zone */ +static void +fr_worker_auth_del(struct worker* worker, struct fast_reload_auth_change* item, + int for_change) +{ + int released = 0; /* Did this routine release callbacks. */ + struct auth_xfer* xfr = NULL; + + lock_rw_wrlock(&item->old_z->lock); + if(item->old_z->zonemd_callback_env && + item->old_z->zonemd_callback_env->worker == worker){ + /* This worker was performing a zonemd lookup, + * stop the lookup and remove that entry. */ + auth_zone_zonemd_stop_lookup(item->old_z, worker->env.mesh); + item->old_z->zonemd_callback_env = NULL; + } + lock_rw_unlock(&item->old_z->lock); + + fr_pickup_auth_locks(worker, item->old_z, item->old_z, NULL, &xfr, + NULL); + lock_rw_unlock(&worker->daemon->fast_reload_thread->old_auth_zones->lock); + lock_rw_unlock(&worker->env.auth_zones->lock); + lock_rw_unlock(&item->old_z->lock); + if(xfr) { + /* Release callbacks on the xfr, if this worker holds them. */ + if(xfr->task_nextprobe->worker == worker || + xfr->task_probe->worker == worker || + xfr->task_transfer->worker == worker) { + released = 1; + xfr_disown_tasks(xfr, worker); + } + lock_basic_unlock(&xfr->lock); + } + + if(!for_change && (released || worker->thread_num == 0)) { + /* See if the xfr item can be deleted. */ + xfr = NULL; + fr_pickup_auth_locks(worker, item->old_z, item->old_z, NULL, + &xfr, NULL); + lock_rw_unlock(&worker->daemon->fast_reload_thread->old_auth_zones->lock); + lock_rw_unlock(&item->old_z->lock); + if(xfr && xfr->task_nextprobe->worker == NULL && + xfr->task_probe->worker == NULL && + xfr->task_transfer->worker == NULL) { + (void)rbtree_delete(&worker->env.auth_zones->xtree, + &xfr->node); + lock_rw_unlock(&worker->env.auth_zones->lock); + lock_basic_unlock(&xfr->lock); + auth_xfer_delete(xfr); + } else { + lock_rw_unlock(&worker->env.auth_zones->lock); + if(xfr) { + lock_basic_unlock(&xfr->lock); + } + } + } +} + +/** Fast reload, auth xfer config is picked up */ +static void +auth_xfr_pickup_config(struct auth_xfer* loadxfr, struct auth_xfer* xfr) +{ + struct auth_master *probe_masters, *transfer_masters; + log_assert(loadxfr->namelen == xfr->namelen); + log_assert(loadxfr->namelabs == xfr->namelabs); + log_assert(loadxfr->dclass == xfr->dclass); + + /* The lists can be swapped in, the other xfr struct will be deleted + * afterwards. */ + probe_masters = xfr->task_probe->masters; + transfer_masters = xfr->task_transfer->masters; + xfr->task_probe->masters = loadxfr->task_probe->masters; + xfr->task_transfer->masters = loadxfr->task_transfer->masters; + loadxfr->task_probe->masters = probe_masters; + loadxfr->task_transfer->masters = transfer_masters; +} + +/** Fast reload, worker picks up added auth zone */ +static void +fr_worker_auth_add(struct worker* worker, struct fast_reload_auth_change* item, + int for_change) +{ + struct auth_xfer* xfr = NULL, *loadxfr = NULL; + + /* Start zone transfers and lookups. */ + fr_pickup_auth_locks(worker, item->new_z, NULL, item->new_z, &xfr, + &loadxfr); + if(xfr == NULL && item->new_z->zone_is_slave) { + /* The xfr item needs to be created. The auth zones lock + * is held to make this possible. */ + xfr = auth_xfer_create(worker->env.auth_zones, item->new_z); + auth_xfr_pickup_config(loadxfr, xfr); + /* Serial information is copied into the xfr struct. */ + if(!xfr_find_soa(item->new_z, xfr)) { + xfr->serial = 0; + } + } else if(for_change && xfr) { + if(!xfr_find_soa(item->new_z, xfr)) { + xfr->serial = 0; + } + } + lock_rw_unlock(&item->new_z->lock); + lock_rw_unlock(&worker->env.auth_zones->lock); + lock_rw_unlock(&worker->daemon->fast_reload_thread->old_auth_zones->lock); + if(loadxfr) { + lock_basic_unlock(&loadxfr->lock); + } + if(xfr) { + auth_xfer_pickup_initial_zone(xfr, &worker->env); + if(for_change) { + xfr->task_probe->only_lookup = 0; + } + lock_basic_unlock(&xfr->lock); + } + + /* Perform ZONEMD verification lookups. */ + lock_rw_wrlock(&item->new_z->lock); + /* holding only the new_z lock */ + auth_zone_verify_zonemd(item->new_z, &worker->env, + &worker->env.mesh->mods, NULL, 0, 1); + lock_rw_unlock(&item->new_z->lock); +} + +/** Fast reload, worker picks up changed auth zone */ +static void +fr_worker_auth_cha(struct worker* worker, struct fast_reload_auth_change* item) +{ + int todelete = 0; + struct auth_xfer* loadxfr = NULL, *xfr = NULL; + /* Since the zone has been changed, by rereading it from zone file, + * existing transfers and probes are likely for the old version. + * Stop them, and start new ones if needed. */ + fr_worker_auth_del(worker, item, 1); + + if(worker->thread_num != 0) + return; + + /* The old callbacks are stopped, tasks have been disowned. The + * new config contents can be picked up. SOA information is picked + * up in the auth_add routine, as it has the new_z ready. */ + + fr_pickup_auth_locks(worker, item->new_z, item->old_z, item->new_z, + &xfr, &loadxfr); + + /* The xfr is not there any more if the zone is not set to have + * zone transfers. Or the xfr needs to be created if it is set to + * have zone transfers. */ + if(loadxfr && xfr) { + /* Copy the config from loadxfr to the xfr in current use. */ + auth_xfr_pickup_config(loadxfr, xfr); + } else if(!loadxfr && xfr) { + /* Delete the xfr. */ + (void)rbtree_delete(&worker->env.auth_zones->xtree, + &xfr->node); + todelete = 1; + item->new_z->zone_is_slave = 0; + } else if(loadxfr && !xfr) { + /* Create the xfr. */ + xfr = auth_xfer_create(worker->env.auth_zones, item->new_z); + auth_xfr_pickup_config(loadxfr, xfr); + item->new_z->zone_is_slave = 1; + } + lock_rw_unlock(&item->new_z->lock); + lock_rw_unlock(&item->old_z->lock); + lock_rw_unlock(&worker->daemon->fast_reload_thread->old_auth_zones->lock); + lock_rw_unlock(&worker->env.auth_zones->lock); + if(loadxfr) { + lock_basic_unlock(&loadxfr->lock); + } + if(xfr) { + lock_basic_unlock(&xfr->lock); + } + if(todelete) { + auth_xfer_delete(xfr); + } + + fr_worker_auth_add(worker, item, 1); +} + +/** Fast reload, the worker picks up changes in auth zones. */ +static void +fr_worker_pickup_auth_changes(struct worker* worker, + struct fast_reload_auth_change* auth_zone_change_list) +{ + struct fast_reload_auth_change* item; + for(item = auth_zone_change_list; item; item = item->next) { + if(item->is_deleted) { + fr_worker_auth_del(worker, item, 0); + } + if(item->is_added) { + if(worker->thread_num == 0) { + fr_worker_auth_add(worker, item, 0); + } + } + if(item->is_changed) { + fr_worker_auth_cha(worker, item); + } + } +} + +/** Fast reload, the worker picks up changes in outside_network. */ +static void +fr_worker_pickup_outside_network(struct worker* worker) +{ + struct outside_network* outnet = worker->back; + struct config_file* cfg = worker->env.cfg; + outnet->use_caps_for_id = cfg->use_caps_bits_for_id; + outnet->unwanted_threshold = cfg->unwanted_threshold; + outnet->tls_use_sni = cfg->tls_use_sni; + outnet->tcp_mss = cfg->outgoing_tcp_mss; + outnet->ip_dscp = cfg->ip_dscp; + outnet->max_reuse_tcp_queries = cfg->max_reuse_tcp_queries; + outnet->tcp_reuse_timeout = cfg->tcp_reuse_timeout; + outnet->tcp_auth_query_timeout = cfg->tcp_auth_query_timeout; + outnet->delayclose = cfg->delay_close; + if(outnet->delayclose) { +#ifndef S_SPLINT_S + outnet->delay_tv.tv_sec = cfg->delay_close/1000; + outnet->delay_tv.tv_usec = (cfg->delay_close%1000)*1000; +#endif + } +} + +void +fast_reload_worker_pickup_changes(struct worker* worker) +{ + /* The pickup of changes is called when the fast reload has + * a syncronized moment, and all the threads are paused and the + * reload has been applied. Then the worker can pick up the new + * changes and store them in worker-specific structs. + * The pickup is also called when there is no pause, and then + * it is called after the reload has completed, and the worker + * get a signal to release old information, it can then pick + * up the new information. But in the mean time, the reload has + * swapped in trees, and the worker has been running with the + * older information for some time. */ + fr_worker_pickup_mesh(worker); + + /* If the tcp connection limit has changed, the open connections + * need to remove their reference for the old tcp limits counters. */ + if(worker->daemon->fast_reload_tcl_has_changes) + tcl_remove_old(worker->front); + + /* If there are zonemd lookups, but the zone was deleted, the + * lookups should be cancelled. */ + fr_worker_pickup_auth_changes(worker, + worker->daemon->fast_reload_thread->auth_zone_change_list); +#ifdef USE_CACHEDB + worker->env.cachedb_enabled = worker->daemon->env->cachedb_enabled; +#endif + fr_worker_pickup_outside_network(worker); +} + +/** fast reload thread, handle reload_stop notification, send reload stop + * to other threads over IPC and collect their ack. When that is done, + * ack to the caller, the fast reload thread, and wait for it to send start. */ +static void +fr_main_perform_reload_stop(struct fast_reload_thread* fr) +{ + struct daemon* daemon = fr->worker->daemon; + int i; + + /* Send reload_stop to other threads. */ + for(i=0; i<daemon->num; i++) { + if(i == fr->worker->thread_num) + continue; /* Do not send to ourselves. */ + worker_send_cmd(daemon->workers[i], worker_cmd_reload_stop); + } + + /* Wait for the other threads to ack. */ + fr_read_ack_from_workers(fr); + + /* Send ack to fast reload thread. */ + fr_send_cmd_to(fr, fast_reload_notification_reload_ack, 0, 1); + + /* Wait for reload_start from fast reload thread to resume. */ + fr_poll_for_reload_start(fr); + + /* Send reload_start to other threads */ + for(i=0; i<daemon->num; i++) { + if(i == fr->worker->thread_num) + continue; /* Do not send to ourselves. */ + worker_send_cmd(daemon->workers[i], worker_cmd_reload_start); + } + + /* Pick up changes for this worker. */ + if(fr->worker->daemon->fast_reload_drop_mesh) { + verbose(VERB_ALGO, "worker: drop mesh queries after reload"); + mesh_delete_all(fr->worker->env.mesh); + } + fast_reload_worker_pickup_changes(fr->worker); + + /* Wait for the other threads to ack. */ + fr_read_ack_from_workers(fr); + + /* Send ack to fast reload thread. */ + fr_send_cmd_to(fr, fast_reload_notification_reload_ack, 0, 1); + + verbose(VERB_ALGO, "worker resume after reload"); +} + +/** Fast reload, the main thread performs the nopause poll. It polls every + * other worker thread briefly over the command pipe ipc. The command takes + * no time for the worker, it can return immediately. After that it sends + * an acknowledgement to the fastreload thread. */ +static void +fr_main_perform_reload_nopause_poll(struct fast_reload_thread* fr) +{ + struct daemon* daemon = fr->worker->daemon; + int i; + + /* Send the reload_poll to other threads. They can respond + * one at a time. */ + for(i=0; i<daemon->num; i++) { + if(i == fr->worker->thread_num) + continue; /* Do not send to ourselves. */ + worker_send_cmd(daemon->workers[i], worker_cmd_reload_poll); + } + + /* Wait for the other threads to ack. */ + fr_read_ack_from_workers(fr); + fast_reload_worker_pickup_changes(fr->worker); + + /* Send ack to fast reload thread. */ + fr_send_cmd_to(fr, fast_reload_notification_reload_ack, 0, 1); +} + +/** Fast reload, perform the command received from the fast reload thread */ +static void +fr_main_perform_cmd(struct fast_reload_thread* fr, + enum fast_reload_notification status) +{ + verbose(VERB_ALGO, "main perform fast reload status: %s", + fr_notification_to_string(status)); + if(status == fast_reload_notification_printout) { + fr_main_perform_printout(fr); + } else if(status == fast_reload_notification_done || + status == fast_reload_notification_done_error || + status == fast_reload_notification_exited) { + fr_main_perform_done(fr); + } else if(status == fast_reload_notification_reload_stop) { + fr_main_perform_reload_stop(fr); + } else if(status == fast_reload_notification_reload_nopause_poll) { + fr_main_perform_reload_nopause_poll(fr); + } else { + log_err("main received unknown status from fast reload: %d %s", + (int)status, fr_notification_to_string(status)); + } +} + +/** Fast reload, handle command from fast reload to the main thread. */ +static void +fr_main_handle_cmd(struct fast_reload_thread* fr) +{ + enum fast_reload_notification status; + ssize_t ret; + /* keep static analyzer happy; recv(-1,..) */ + log_assert(fr->commpair[0] >= 0); + ret = recv(fr->commpair[0], + ((char*)&fr->service_read_cmd)+fr->service_read_cmd_count, + sizeof(fr->service_read_cmd)-fr->service_read_cmd_count, 0); + if(ret == -1) { + if( +#ifndef USE_WINSOCK + errno == EINTR || errno == EAGAIN +# ifdef EWOULDBLOCK + || errno == EWOULDBLOCK +# endif +#else + WSAGetLastError() == WSAEINTR || + WSAGetLastError() == WSAEINPROGRESS +#endif + ) + return; /* Continue later. */ +#ifdef USE_WINSOCK + if(WSAGetLastError() == WSAEWOULDBLOCK) { + ub_winsock_tcp_wouldblock(fr->service_event, + UB_EV_READ); + return; /* Continue later. */ + } +#endif + log_err("read cmd from fast reload thread, recv: %s", + sock_strerror(errno)); + return; + } else if(ret == 0) { + verbose(VERB_ALGO, "closed connection from fast reload thread"); + fr->service_read_cmd_count = 0; + /* handle this like an error */ + fr->service_read_cmd = fast_reload_notification_done_error; + } else if(ret + (ssize_t)fr->service_read_cmd_count < + (ssize_t)sizeof(fr->service_read_cmd)) { + fr->service_read_cmd_count += ret; + /* Continue later. */ + return; + } + status = fr->service_read_cmd; + fr->service_read_cmd = 0; + fr->service_read_cmd_count = 0; + fr_main_perform_cmd(fr, status); +} + +/** Fast reload, poll for and handle cmd from fast reload thread. */ +static void +fr_check_cmd_from_thread(struct fast_reload_thread* fr) +{ + int inevent = 0; + struct worker* worker = fr->worker; + /* Stop in case the thread has exited, or there is no read event. */ + while(worker->daemon->fast_reload_thread) { + if(!sock_poll_timeout(fr->commpair[0], 0, 1, 0, &inevent)) { + log_err("check for cmd from fast reload thread: " + "poll failed"); +#ifdef USE_WINSOCK + if(worker->daemon->fast_reload_thread) + ub_winsock_tcp_wouldblock(worker->daemon-> + fast_reload_thread->service_event, + UB_EV_READ); +#endif + return; + } + if(!inevent) { +#ifdef USE_WINSOCK + if(worker->daemon->fast_reload_thread) + ub_winsock_tcp_wouldblock(worker->daemon-> + fast_reload_thread->service_event, + UB_EV_READ); +#endif + return; + } + fr_main_handle_cmd(fr); + } +} + +void fast_reload_service_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(bits), + void* arg) +{ + struct fast_reload_thread* fast_reload_thread = + (struct fast_reload_thread*)arg; + struct worker* worker = fast_reload_thread->worker; + + /* Read and handle the command */ + fr_main_handle_cmd(fast_reload_thread); + if(worker->daemon->fast_reload_thread != NULL) { + /* If not exited, see if there are more pending statuses + * from the fast reload thread. */ + fr_check_cmd_from_thread(fast_reload_thread); + } +} + +#ifdef HAVE_SSL +/** fast reload, send client item over SSL. Returns number of bytes + * printed, 0 on wait later, or -1 on failure. */ +static int +fr_client_send_item_ssl(struct fast_reload_printq* printq) +{ + int r; + ERR_clear_error(); + r = SSL_write(printq->remote.ssl, + printq->client_item+printq->client_byte_count, + printq->client_len - printq->client_byte_count); + if(r <= 0) { + int want = SSL_get_error(printq->remote.ssl, r); + if(want == SSL_ERROR_ZERO_RETURN) { + log_err("fast_reload print to remote client: " + "SSL_write says connection closed."); + return -1; + } else if(want == SSL_ERROR_WANT_READ) { + /* wait for read condition */ + printq->client_cp->ssl_shake_state = comm_ssl_shake_hs_read; + comm_point_listen_for_rw(printq->client_cp, 1, 0); + return 0; + } else if(want == SSL_ERROR_WANT_WRITE) { +#ifdef USE_WINSOCK + ub_winsock_tcp_wouldblock(comm_point_internal(printq->client_cp), UB_EV_WRITE); +#endif + return 0; /* write more later */ + } else if(want == SSL_ERROR_SYSCALL) { +#ifdef EPIPE + if(errno == EPIPE && verbosity < 2) { + /* silence 'broken pipe' */ + return -1; + } +#endif + if(errno != 0) + log_err("fast_reload print to remote client: " + "SSL_write syscall: %s", + sock_strerror(errno)); + return -1; + } + log_crypto_err_io("fast_reload print to remote client: " + "could not SSL_write", want); + return -1; + } + return r; +} +#endif /* HAVE_SSL */ + +/** fast reload, send client item for fd, returns bytes sent, or 0 for wait + * later, or -1 on failure. */ +static int +fr_client_send_item_fd(struct fast_reload_printq* printq) +{ + int r; + r = (int)send(printq->remote.fd, + printq->client_item+printq->client_byte_count, + printq->client_len - printq->client_byte_count, 0); + if(r == -1) { + if( +#ifndef USE_WINSOCK + errno == EINTR || errno == EAGAIN +# ifdef EWOULDBLOCK + || errno == EWOULDBLOCK +# endif +#else + WSAGetLastError() == WSAEINTR || + WSAGetLastError() == WSAEINPROGRESS || + WSAGetLastError() == WSAEWOULDBLOCK +#endif + ) { +#ifdef USE_WINSOCK + ub_winsock_tcp_wouldblock(comm_point_internal(printq->client_cp), UB_EV_WRITE); +#endif + return 0; /* Try again. */ + } + log_err("fast_reload print to remote client: send failed: %s", + sock_strerror(errno)); + return -1; + } + return r; +} + +/** fast reload, send current client item. false on failure or wait later. */ +static int +fr_client_send_item(struct fast_reload_printq* printq) +{ + int r; +#ifdef HAVE_SSL + if(printq->remote.ssl) { + r = fr_client_send_item_ssl(printq); + } else { +#endif + r = fr_client_send_item_fd(printq); +#ifdef HAVE_SSL + } +#endif + if(r == 0) { + /* Wait for later. */ + return 0; + } else if(r == -1) { + /* It failed, close comm point and stop sending. */ + fr_printq_remove(printq); + return 0; + } + printq->client_byte_count += r; + if(printq->client_byte_count < printq->client_len) + return 0; /* Print more later. */ + return 1; +} + +/** fast reload, pick up the next item to print */ +static void +fr_client_pickup_next_item(struct fast_reload_printq* printq) +{ + struct config_strlist* item; + /* Pop first off the list. */ + if(!printq->to_print->first) { + printq->client_item = NULL; + printq->client_len = 0; + printq->client_byte_count = 0; + return; + } + item = printq->to_print->first; + if(item->next) { + printq->to_print->first = item->next; + } else { + printq->to_print->first = NULL; + printq->to_print->last = NULL; + } + item->next = NULL; + printq->client_len = 0; + printq->client_byte_count = 0; + printq->client_item = item->str; + item->str = NULL; + free(item); + /* The len is the number of bytes to print out, and thus excludes + * the terminator zero. */ + if(printq->client_item) + printq->client_len = (int)strlen(printq->client_item); +} + +int fast_reload_client_callback(struct comm_point* ATTR_UNUSED(c), void* arg, + int err, struct comm_reply* ATTR_UNUSED(rep)) +{ + struct fast_reload_printq* printq = (struct fast_reload_printq*)arg; + if(!printq->client_cp) { + fr_printq_remove(printq); + return 0; /* the output is closed and deleted */ + } + if(err != NETEVENT_NOERROR) { + verbose(VERB_ALGO, "fast reload client: error, close it"); + fr_printq_remove(printq); + return 0; + } +#ifdef HAVE_SSL + if(printq->client_cp->ssl_shake_state == comm_ssl_shake_hs_read) { + /* read condition satisfied back to writing */ + comm_point_listen_for_rw(printq->client_cp, 0, 1); + printq->client_cp->ssl_shake_state = comm_ssl_shake_none; + } +#endif /* HAVE_SSL */ + + /* Pickup an item if there are none */ + if(!printq->client_item) { + fr_client_pickup_next_item(printq); + } + if(!printq->client_item) { + if(printq->in_list) { + /* Nothing more to print, it can be removed. */ + fr_printq_remove(printq); + return 0; + } + /* Done with printing for now. */ + comm_point_stop_listening(printq->client_cp); + return 0; + } + + /* Try to print out a number of items, if they can print in full. */ + while(printq->client_item) { + /* Send current item, if any. */ + if(printq->client_item && printq->client_len != 0 && + printq->client_byte_count < printq->client_len) { + if(!fr_client_send_item(printq)) + return 0; + } + + /* The current item is done. */ + if(printq->client_item) { + free(printq->client_item); + printq->client_item = NULL; + printq->client_len = 0; + printq->client_byte_count = 0; + } + if(!printq->to_print->first) { + if(printq->in_list) { + /* Nothing more to print, it can be removed. */ + fr_printq_remove(printq); + return 0; + } + /* Done with printing for now. */ + comm_point_stop_listening(printq->client_cp); + return 0; + } + fr_client_pickup_next_item(printq); + } + + return 0; +} + +#ifndef THREADS_DISABLED +/** fast reload printq create */ +static struct fast_reload_printq* +fr_printq_create(struct comm_point* c, struct worker* worker) +{ + struct fast_reload_printq* printq = calloc(1, sizeof(*printq)); + if(!printq) + return NULL; + printq->to_print = calloc(1, sizeof(*printq->to_print)); + if(!printq->to_print) { + free(printq); + return NULL; + } + printq->worker = worker; + printq->client_cp = c; + printq->client_cp->callback = fast_reload_client_callback; + printq->client_cp->cb_arg = printq; + return printq; +} +#endif /* !THREADS_DISABLED */ + +/** fast reload printq delete */ +static void +fr_printq_delete(struct fast_reload_printq* printq) +{ + if(!printq) + return; +#ifdef HAVE_SSL + if(printq->remote.ssl) { + SSL_shutdown(printq->remote.ssl); + SSL_free(printq->remote.ssl); + } +#endif + comm_point_delete(printq->client_cp); + if(printq->to_print) { + config_delstrlist(printq->to_print->first); + free(printq->to_print); + } + free(printq); +} + +/** fast reload printq, returns true if the list is empty and no item */ +static int +fr_printq_empty(struct fast_reload_printq* printq) +{ + if(printq->to_print->first == NULL && printq->client_item == NULL) + return 1; + return 0; +} + +/** fast reload printq, insert onto list */ +static void +fr_printq_list_insert(struct fast_reload_printq* printq, struct daemon* daemon) +{ + if(printq->in_list) + return; + printq->next = daemon->fast_reload_printq_list; + if(printq->next) + printq->next->prev = printq; + printq->prev = NULL; + printq->in_list = 1; + daemon->fast_reload_printq_list = printq; +} + +/** fast reload printq delete list */ +void +fast_reload_printq_list_delete(struct fast_reload_printq* list) +{ + struct fast_reload_printq* printq = list, *next; + while(printq) { + next = printq->next; + fr_printq_delete(printq); + printq = next; + } +} + +/** fast reload printq remove the item from the printq list */ +static void +fr_printq_list_remove(struct fast_reload_printq* printq) +{ + struct daemon* daemon = printq->worker->daemon; + if(printq->prev == NULL) + daemon->fast_reload_printq_list = printq->next; + else printq->prev->next = printq->next; + if(printq->next) + printq->next->prev = printq->prev; + printq->in_list = 0; +} + +/** fast reload printq, remove the printq when no longer needed, + * like the stream is closed. */ +static void +fr_printq_remove(struct fast_reload_printq* printq) +{ + if(!printq) + return; + if(printq->worker->daemon->fast_reload_thread && + printq->worker->daemon->fast_reload_thread->printq == printq) + printq->worker->daemon->fast_reload_thread->printq = NULL; + if(printq->in_list) + fr_printq_list_remove(printq); + fr_printq_delete(printq); +} + +/** fast reload thread, send stop command to the thread, from the main thread. + */ +static void +fr_send_stop(struct fast_reload_thread* fr) +{ + fr_send_cmd_to(fr, fast_reload_notification_exit, 1, 0); +} + +void +fast_reload_thread_start(RES* ssl, struct worker* worker, struct rc_state* s, + int fr_verb, int fr_nopause, int fr_drop_mesh) +{ + if(worker->daemon->fast_reload_thread) { + log_err("fast reload thread already running"); + return; + } + if(!fast_reload_thread_setup(worker, fr_verb, fr_nopause, + fr_drop_mesh)) { + if(!ssl_printf(ssl, "error could not setup thread\n")) + return; + return; + } + worker->daemon->fast_reload_thread->started = 1; + +#ifndef THREADS_DISABLED + /* Setup command listener in remote servicing thread */ + /* The listener has to be nonblocking, so the the remote servicing + * thread can continue to service DNS queries, the fast reload + * thread is going to read the config from disk and apply it. */ + /* The commpair[1] element can stay blocking, it is used by the + * fast reload thread to communicate back. The thread needs to wait + * at these times, when it has to check briefly it can use poll. */ + fd_set_nonblock(worker->daemon->fast_reload_thread->commpair[0]); + worker->daemon->fast_reload_thread->service_event = ub_event_new( + comm_base_internal(worker->base), + worker->daemon->fast_reload_thread->commpair[0], + UB_EV_READ | UB_EV_PERSIST, fast_reload_service_cb, + worker->daemon->fast_reload_thread); + if(!worker->daemon->fast_reload_thread->service_event) { + fast_reload_thread_desetup(worker->daemon->fast_reload_thread); + if(!ssl_printf(ssl, "error out of memory\n")) + return; + return; + } + if(ub_event_add(worker->daemon->fast_reload_thread->service_event, + NULL) != 0) { + fast_reload_thread_desetup(worker->daemon->fast_reload_thread); + if(!ssl_printf(ssl, "error out of memory adding service event\n")) + return; + return; + } + worker->daemon->fast_reload_thread->service_event_is_added = 1; + + /* Setup the comm point to the remote control client as an event + * on the remote servicing thread, which it already is. + * It needs a new callback to service it. */ + log_assert(s); + state_list_remove_elem(&s->rc->busy_list, s->c); + s->rc->active --; + /* Set the comm point file descriptor to nonblocking. So that + * printout to the remote control client does not block the + * server thread from servicing DNS queries. */ + fd_set_nonblock(s->c->fd); + worker->daemon->fast_reload_thread->printq = fr_printq_create(s->c, + worker); + if(!worker->daemon->fast_reload_thread->printq) { + fast_reload_thread_desetup(worker->daemon->fast_reload_thread); + if(!ssl_printf(ssl, "error out of memory create printq\n")) + return; + return; + } + worker->daemon->fast_reload_thread->printq->remote = *ssl; + s->rc = NULL; /* move away the rc state */ + /* Nothing to print right now, so no need to have it active. */ + comm_point_stop_listening(worker->daemon->fast_reload_thread->printq->client_cp); + + /* Start fast reload thread */ + ub_thread_create(&worker->daemon->fast_reload_thread->tid, + fast_reload_thread_main, worker->daemon->fast_reload_thread); +#else + (void)s; +#endif +} + +void +fast_reload_thread_stop(struct fast_reload_thread* fast_reload_thread) +{ + struct worker* worker = fast_reload_thread->worker; + if(!fast_reload_thread) + return; + fr_send_stop(fast_reload_thread); + if(worker->daemon->fast_reload_thread != NULL) { + /* If it did not exit yet, join with the thread now. It is + * going to exit because the exit command is sent to it. */ + fr_main_perform_done(fast_reload_thread); + } +} diff --git a/daemon/remote.h b/daemon/remote.h index 4902803f5e42..064d7b7fccce 100644 --- a/daemon/remote.h +++ b/daemon/remote.h @@ -48,6 +48,7 @@ #ifdef HAVE_OPENSSL_SSL_H #include <openssl/ssl.h> #endif +#include "util/locks.h" struct config_file; struct listen_list; struct listen_port; @@ -55,6 +56,7 @@ struct worker; struct comm_reply; struct comm_point; struct daemon_remote; +struct config_strlist_head; /** number of milliseconds timeout on incoming remote control handshake */ #define REMOTE_CONTROL_TCP_TIMEOUT 120000 @@ -119,6 +121,137 @@ struct remote_stream { typedef struct remote_stream RES; /** + * Notification status. This is exchanged between the fast reload thread + * and the server thread, over the commpair sockets. + */ +enum fast_reload_notification { + /** nothing, not used */ + fast_reload_notification_none = 0, + /** the fast reload thread is done */ + fast_reload_notification_done = 1, + /** the fast reload thread is done but with an error, it failed */ + fast_reload_notification_done_error = 2, + /** the fast reload thread is told to exit by the server thread. + * Sent on server quit while the reload is running. */ + fast_reload_notification_exit = 3, + /** the fast reload thread has exited, after being told to exit */ + fast_reload_notification_exited = 4, + /** the fast reload thread has information to print out */ + fast_reload_notification_printout = 5, + /** stop as part of the reload the thread and other threads */ + fast_reload_notification_reload_stop = 6, + /** ack the stop as part of the reload, and also ack start */ + fast_reload_notification_reload_ack = 7, + /** resume from stop as part of the reload */ + fast_reload_notification_reload_start = 8, + /** the fast reload thread wants the mainthread to poll workers, + * after the reload, sent when nopause is used */ + fast_reload_notification_reload_nopause_poll = 9 +}; + +/** + * Fast reload printout queue. Contains a list of strings, that need to be + * printed over the file descriptor. + */ +struct fast_reload_printq { + /** if this item is in a list, the previous and next */ + struct fast_reload_printq *prev, *next; + /** if this item is in a list, it is true. */ + int in_list; + /** list of strings to printout */ + struct config_strlist_head* to_print; + /** the current item to print. It is malloced. NULL if none. */ + char* client_item; + /** The length, strlen, of the client_item, that has to be sent. */ + int client_len; + /** The number of bytes sent of client_item. */ + int client_byte_count; + /** the comm point for the client connection, the remote control + * client. */ + struct comm_point* client_cp; + /** the remote control connection to print output to. */ + struct remote_stream remote; + /** the worker that the event is added in */ + struct worker* worker; +}; + +/** + * Fast reload auth zone change. Keeps track if an auth zone was removed, + * added or changed. This is needed because workers can have events for + * dealing with auth zones, like transfers, and those have to be removed + * too, not just the auth zone structure from the tree. */ +struct fast_reload_auth_change { + /** next in the list of auth zone changes. */ + struct fast_reload_auth_change* next; + /** the zone in the old config */ + struct auth_zone* old_z; + /** the zone in the new config */ + struct auth_zone* new_z; + /** if the zone was deleted */ + int is_deleted; + /** if the zone was added */ + int is_added; + /** if the zone has been changed */ + int is_changed; +}; + +/** + * Fast reload thread structure + */ +struct fast_reload_thread { + /** the thread number for the dtio thread, + * must be first to cast thread arg to int* in checklock code. */ + int threadnum; + /** communication socket pair, that sends commands */ + int commpair[2]; + /** thread id, of the io thread */ + ub_thread_type tid; + /** if the io processing has started */ + int started; + /** if the thread has to quit */ + int need_to_quit; + /** verbosity of the fast_reload command, the number of +v options */ + int fr_verb; + /** option to not pause threads during reload */ + int fr_nopause; + /** option to drop mesh queries */ + int fr_drop_mesh; + + /** the event that listens on the remote service worker to the + * commpair, it receives content from the fast reload thread. */ + void* service_event; + /** if the event that listens on the remote service worker has + * been added to the comm base. */ + int service_event_is_added; + /** the service event can read a cmd, nonblocking, so it can + * save the partial read cmd here */ + uint32_t service_read_cmd; + /** the number of bytes in service_read_cmd */ + int service_read_cmd_count; + /** the worker that the service_event is added in */ + struct worker* worker; + + /** the printout of output to the remote client. */ + struct fast_reload_printq *printq; + + /** lock on fr_output, to stop race when both remote control thread + * and fast reload thread use fr_output list. */ + lock_basic_type fr_output_lock; + /** list of strings, that the fast reload thread produces that have + * to be printed. The remote control thread can pick them up with + * the lock. */ + struct config_strlist_head* fr_output; + + /** communication socket pair, to respond to the reload request */ + int commreload[2]; + + /** the list of auth zone changes. */ + struct fast_reload_auth_change* auth_zone_change_list; + /** the old tree of auth zones, to lookup. */ + struct auth_zones* old_auth_zones; +}; + +/** * Create new remote control state for the daemon. * @param cfg: config file with key file settings. * @return new state, or NULL on failure. @@ -203,4 +336,38 @@ int ssl_printf(RES* ssl, const char* format, ...) int ssl_read_line(RES* ssl, char* buf, size_t max); #endif /* HAVE_SSL */ +/** + * Start fast reload thread + * @param ssl: the RES connection to print to. + * @param worker: the remote servicing worker. + * @param s: the rc_state that is servicing the remote control connection to + * the remote control client. It needs to be moved away to stay connected + * while the fast reload is running. + * @param fr_verb: verbosity to print output at. 0 is nothing, 1 is some + * and 2 is more detail. + * @param fr_nopause: option to not pause threads during reload. + * @param fr_drop_mesh: option to drop mesh queries. + */ +void fast_reload_thread_start(RES* ssl, struct worker* worker, + struct rc_state* s, int fr_verb, int fr_nopause, int fr_drop_mesh); + +/** + * Stop fast reload thread + * @param fast_reload_thread: the thread struct. + */ +void fast_reload_thread_stop(struct fast_reload_thread* fast_reload_thread); + +/** fast reload thread commands to remote service thread event callback */ +void fast_reload_service_cb(int fd, short bits, void* arg); + +/** fast reload callback for the remote control client connection */ +int fast_reload_client_callback(struct comm_point* c, void* arg, int err, + struct comm_reply* rep); + +/** fast reload printq delete list */ +void fast_reload_printq_list_delete(struct fast_reload_printq* list); + +/** Pick up per worker changes after a fast reload. */ +void fast_reload_worker_pickup_changes(struct worker* worker); + #endif /* DAEMON_REMOTE_H */ diff --git a/daemon/stats.c b/daemon/stats.c index 0e17300a150e..7efb83a0bc3f 100644 --- a/daemon/stats.c +++ b/daemon/stats.c @@ -281,6 +281,12 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset) s->svr.rpz_action[i] += (long long)worker->env.mesh->rpz_action[i]; timehist_export(worker->env.mesh->histogram, s->svr.hist, NUM_BUCKETS_HIST); + s->svr.num_queries_discard_timeout += + (long long)worker->env.mesh->num_queries_discard_timeout; + s->svr.num_queries_wait_limit += + (long long)worker->env.mesh->num_queries_wait_limit; + s->svr.num_dns_error_reports += + (long long)worker->env.mesh->num_dns_error_reports; /* values from outside network */ s->svr.unwanted_replies = (long long)worker->back->unwanted_replies; s->svr.qtcp_outgoing = (long long)worker->back->num_tcp_outgoing; @@ -325,20 +331,8 @@ server_stats_compile(struct worker* worker, struct ub_stats_info* s, int reset) s->svr.num_query_dnscrypt_replay = 0; #endif /* USE_DNSCRYPT */ if(worker->env.auth_zones) { - if(reset && !worker->env.cfg->stat_cumulative) { - lock_rw_wrlock(&worker->env.auth_zones->lock); - } else { - lock_rw_rdlock(&worker->env.auth_zones->lock); - } - s->svr.num_query_authzone_up = (long long)worker->env. - auth_zones->num_query_up; - s->svr.num_query_authzone_down = (long long)worker->env. - auth_zones->num_query_down; - if(reset && !worker->env.cfg->stat_cumulative) { - worker->env.auth_zones->num_query_up = 0; - worker->env.auth_zones->num_query_down = 0; - } - lock_rw_unlock(&worker->env.auth_zones->lock); + s->svr.num_query_authzone_up += (long long)worker->env.mesh->num_query_authzone_up; + s->svr.num_query_authzone_down += (long long)worker->env.mesh->num_query_authzone_down; } s->svr.mem_stream_wait = (long long)tcp_req_info_get_stream_buffer_size(); @@ -451,9 +445,15 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a) total->svr.num_queries_cookie_valid += a->svr.num_queries_cookie_valid; total->svr.num_queries_cookie_client += a->svr.num_queries_cookie_client; total->svr.num_queries_cookie_invalid += a->svr.num_queries_cookie_invalid; + total->svr.num_queries_discard_timeout += + a->svr.num_queries_discard_timeout; + total->svr.num_queries_wait_limit += a->svr.num_queries_wait_limit; + total->svr.num_dns_error_reports += a->svr.num_dns_error_reports; total->svr.num_queries_missed_cache += a->svr.num_queries_missed_cache; total->svr.num_queries_prefetch += a->svr.num_queries_prefetch; total->svr.num_queries_timed_out += a->svr.num_queries_timed_out; + total->svr.num_query_authzone_up += a->svr.num_query_authzone_up; + total->svr.num_query_authzone_down += a->svr.num_query_authzone_down; if (total->svr.max_query_time_us < a->svr.max_query_time_us) total->svr.max_query_time_us = a->svr.max_query_time_us; total->svr.sum_query_list_size += a->svr.sum_query_list_size; @@ -461,9 +461,9 @@ void server_stats_add(struct ub_stats_info* total, struct ub_stats_info* a) #ifdef USE_DNSCRYPT total->svr.num_query_dnscrypt_crypted += a->svr.num_query_dnscrypt_crypted; total->svr.num_query_dnscrypt_cert += a->svr.num_query_dnscrypt_cert; - total->svr.num_query_dnscrypt_cleartext += \ + total->svr.num_query_dnscrypt_cleartext += a->svr.num_query_dnscrypt_cleartext; - total->svr.num_query_dnscrypt_crypted_malformed += \ + total->svr.num_query_dnscrypt_crypted_malformed += a->svr.num_query_dnscrypt_crypted_malformed; #endif /* USE_DNSCRYPT */ /* the max size reached is upped to higher of both */ diff --git a/daemon/unbound.c b/daemon/unbound.c index 306fe6caf927..8e59bb25a725 100644 --- a/daemon/unbound.c +++ b/daemon/unbound.c @@ -463,6 +463,64 @@ detach(void) #endif /* HAVE_DAEMON */ } +/* setup a listening ssl context, fatal_exit() on any failure */ +static void +setup_listen_sslctx(void** ctx, int is_dot, int is_doh, struct config_file* cfg) +{ +#ifdef HAVE_SSL + if(!(*ctx = listen_sslctx_create( + cfg->ssl_service_key, cfg->ssl_service_pem, NULL, + cfg->tls_ciphers, cfg->tls_ciphersuites, + (cfg->tls_session_ticket_keys.first && + cfg->tls_session_ticket_keys.first->str[0] != 0), + is_dot, is_doh))) { + fatal_exit("could not set up listen SSL_CTX"); + } +#else /* HAVE_SSL */ + (void)ctx;(void)is_dot;(void)is_doh;(void)cfg; +#endif /* HAVE_SSL */ +} + +/* setups the needed ssl contexts, fatal_exit() on any failure */ +static void +setup_sslctxs(struct daemon* daemon, struct config_file* cfg) +{ +#ifdef HAVE_SSL + if(!(daemon->rc = daemon_remote_create(cfg))) + fatal_exit("could not set up remote-control"); + if(cfg->ssl_service_key && cfg->ssl_service_key[0]) { + /* setup the session keys; the callback to use them will be + * attached to each sslctx separately */ + if(cfg->tls_session_ticket_keys.first && + cfg->tls_session_ticket_keys.first->str[0] != 0) { + if(!listen_sslctx_setup_ticket_keys( + cfg->tls_session_ticket_keys.first)) { + fatal_exit("could not set session ticket SSL_CTX"); + } + } + (void)setup_listen_sslctx(&daemon->listen_dot_sslctx, 1, 0, cfg); +#ifdef HAVE_NGHTTP2_NGHTTP2_H + if(cfg_has_https(cfg)) { + (void)setup_listen_sslctx(&daemon->listen_doh_sslctx, 0, 1, cfg); + } +#endif +#ifdef HAVE_NGTCP2 + if(cfg_has_quic(cfg)) { + if(!(daemon->listen_quic_sslctx = quic_sslctx_create( + cfg->ssl_service_key, cfg->ssl_service_pem, NULL))) { + fatal_exit("could not set up quic SSL_CTX"); + } + } +#endif /* HAVE_NGTCP2 */ + } + if(!(daemon->connect_dot_sslctx = connect_sslctx_create(NULL, NULL, + cfg->tls_cert_bundle, cfg->tls_win_cert))) + fatal_exit("could not set up connect SSL_CTX"); +#else /* HAVE_SSL */ + (void)daemon;(void)cfg; +#endif /* HAVE_SSL */ +} + /** daemonize, drop user privileges and chroot if needed */ static void perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode, @@ -489,36 +547,7 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode, #endif /* read ssl keys while superuser and outside chroot */ -#ifdef HAVE_SSL - if(!(daemon->rc = daemon_remote_create(cfg))) - fatal_exit("could not set up remote-control"); - if(cfg->ssl_service_key && cfg->ssl_service_key[0]) { - if(!(daemon->listen_sslctx = listen_sslctx_create( - cfg->ssl_service_key, cfg->ssl_service_pem, NULL))) - fatal_exit("could not set up listen SSL_CTX"); - if(cfg->tls_ciphers && cfg->tls_ciphers[0]) { - if (!SSL_CTX_set_cipher_list(daemon->listen_sslctx, cfg->tls_ciphers)) { - fatal_exit("failed to set tls-cipher %s", cfg->tls_ciphers); - } - } -#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES - if(cfg->tls_ciphersuites && cfg->tls_ciphersuites[0]) { - if (!SSL_CTX_set_ciphersuites(daemon->listen_sslctx, cfg->tls_ciphersuites)) { - fatal_exit("failed to set tls-ciphersuites %s", cfg->tls_ciphersuites); - } - } -#endif - if(cfg->tls_session_ticket_keys.first && - cfg->tls_session_ticket_keys.first->str[0] != 0) { - if(!listen_sslctx_setup_ticket_keys(daemon->listen_sslctx, cfg->tls_session_ticket_keys.first)) { - fatal_exit("could not set session ticket SSL_CTX"); - } - } - } - if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL, - cfg->tls_cert_bundle, cfg->tls_win_cert))) - fatal_exit("could not set up connect SSL_CTX"); -#endif + (void)setup_sslctxs(daemon, cfg); /* init syslog (as root) if needed, before daemonize, otherwise * a fork error could not be printed since daemonize closed stderr.*/ @@ -681,6 +710,9 @@ perform_setup(struct daemon* daemon, struct config_file* cfg, int debug_mode, * it would succeed on SIGHUP as well */ if(!cfg->use_syslog) log_init(cfg->logfile, cfg->use_syslog, cfg->chrootdir); + daemon->cfgfile = strdup(*cfgfile); + if(!daemon->cfgfile) + fatal_exit("out of memory in daemon cfgfile strdup"); } /** diff --git a/daemon/worker.c b/daemon/worker.c index 713de316373a..ead20938e172 100644 --- a/daemon/worker.c +++ b/daemon/worker.c @@ -371,6 +371,84 @@ worker_check_request(sldns_buffer* pkt, struct worker* worker, return; } +/** + * Send fast-reload acknowledgement to the mainthread in one byte. + * This signals that this worker has received the previous command. + * The worker is waiting if that is after a reload_stop command. + * Or the worker has briefly processed the event itself, and in doing so + * released data pointers to old config, after a reload_poll command. + */ +static void +worker_send_reload_ack(struct worker* worker) +{ + /* If this is clipped to 8 bits because thread_num>255, then that + * is not a problem, the receiver counts the number of bytes received. + * The number is informative only. */ + uint8_t c = (uint8_t)worker->thread_num; + ssize_t ret; + while(1) { + ret = send(worker->daemon->fast_reload_thread->commreload[1], + (void*)&c, 1, 0); + if(ret == -1) { + if( +#ifndef USE_WINSOCK + errno == EINTR || errno == EAGAIN +# ifdef EWOULDBLOCK + || errno == EWOULDBLOCK +# endif +#else + WSAGetLastError() == WSAEINTR || + WSAGetLastError() == WSAEINPROGRESS || + WSAGetLastError() == WSAEWOULDBLOCK +#endif + ) + continue; /* Try again. */ + log_err("worker reload ack reply: send failed: %s", + sock_strerror(errno)); + break; + } + break; + } +} + +/** stop and wait to resume the worker */ +static void +worker_stop_and_wait(struct worker* worker) +{ + uint8_t* buf = NULL; + uint32_t len = 0, cmd; + worker_send_reload_ack(worker); + /* wait for reload */ + if(!tube_read_msg(worker->cmd, &buf, &len, 0)) { + log_err("worker reload read reply failed"); + return; + } + if(len != sizeof(uint32_t)) { + log_err("worker reload reply, bad control msg length %d", + (int)len); + free(buf); + return; + } + cmd = sldns_read_uint32(buf); + free(buf); + if(cmd == worker_cmd_quit) { + /* quit anyway */ + verbose(VERB_ALGO, "reload reply, control cmd quit"); + comm_base_exit(worker->base); + return; + } + if(cmd != worker_cmd_reload_start) { + log_err("worker reload reply, wrong reply command"); + } + if(worker->daemon->fast_reload_drop_mesh) { + verbose(VERB_ALGO, "worker: drop mesh queries after reload"); + mesh_delete_all(worker->env.mesh); + } + fast_reload_worker_pickup_changes(worker); + worker_send_reload_ack(worker); + verbose(VERB_ALGO, "worker resume after reload"); +} + void worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), uint8_t* msg, size_t len, int error, void* arg) @@ -406,6 +484,15 @@ worker_handle_control_cmd(struct tube* ATTR_UNUSED(tube), uint8_t* msg, verbose(VERB_ALGO, "got control cmd remote"); daemon_remote_exec(worker); break; + case worker_cmd_reload_stop: + verbose(VERB_ALGO, "got control cmd reload_stop"); + worker_stop_and_wait(worker); + break; + case worker_cmd_reload_poll: + verbose(VERB_ALGO, "got control cmd reload_poll"); + fast_reload_worker_pickup_changes(worker); + worker_send_reload_ack(worker); + break; default: log_err("bad command %d", (int)cmd); break; @@ -600,7 +687,8 @@ apply_respip_action(struct worker* worker, const struct query_info* qinfo, return 1; if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, &actinfo, - alias_rrset, 0, worker->scratchpad, az, NULL)) + alias_rrset, 0, worker->scratchpad, az, NULL, + worker->env.views, worker->env.respip_set)) return 0; /* xxx_deny actions mean dropping the reply, unless the original reply @@ -761,7 +849,8 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo, } else if(partial_rep && !respip_merge_cname(partial_rep, qinfo, rep, cinfo, must_validate, &encode_rep, worker->scratchpad, - worker->env.auth_zones)) { + worker->env.auth_zones, worker->env.views, + worker->env.respip_set)) { goto bail_out; } if(encode_rep != rep) { @@ -1082,7 +1171,7 @@ answer_notify(struct worker* w, struct query_info* qinfo, if(verbosity >= VERB_DETAIL) { char buf[380]; - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; char sr[25]; dname_str(qinfo->qname, zname); sr[0]=0; @@ -1413,7 +1502,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error, return 0; } if(c->dnscrypt && !repinfo->is_dnscrypted) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; /* Check if this is unencrypted and asking for certs */ worker_check_request(c->buffer, worker, &check_result); if(check_result.value != 0) { @@ -1813,7 +1902,7 @@ worker_handle_request(struct comm_point* c, void* arg, int error, cinfo_tmp.tag_datas = acladdr->tag_datas; cinfo_tmp.tag_datas_size = acladdr->tag_datas_size; cinfo_tmp.view = acladdr->view; - cinfo_tmp.respip_set = worker->daemon->respip_set; + cinfo_tmp.view_name = NULL; cinfo = &cinfo_tmp; } @@ -1845,10 +1934,10 @@ lookup_cache: * its qname must be that used for cache * lookup. */ if((worker->env.cfg->prefetch && - *worker->env.now >= rep->prefetch_ttl) || + rep->prefetch_ttl <= *worker->env.now) || (worker->env.cfg->serve_expired && - *worker->env.now > rep->ttl)) { - + rep->ttl < *worker->env.now && + !(*worker->env.now < rep->serve_expired_norec_ttl))) { time_t leeway = rep->ttl - *worker->env.now; if(rep->ttl < *worker->env.now) leeway = 0; @@ -1966,13 +2055,13 @@ send_reply_rc: &repinfo->client_addr, repinfo->client_addrlen, tv, 1, c->buffer, (worker->env.cfg->log_destaddr?(void*)repinfo->c->socket->addr:NULL), - c->type); + c->type, c->ssl); } else { log_reply_info(NO_VERBOSE, &qinfo, &repinfo->client_addr, repinfo->client_addrlen, tv, 1, c->buffer, (worker->env.cfg->log_destaddr?(void*)repinfo->c->socket->addr:NULL), - c->type); + c->type, c->ssl); } } #ifdef USE_DNSCRYPT @@ -2173,10 +2262,11 @@ worker_init(struct worker* worker, struct config_file *cfg, : cfg->tcp_idle_timeout, cfg->harden_large_queries, cfg->http_max_streams, cfg->http_endpoint, cfg->http_notls_downstream, - worker->daemon->tcl, worker->daemon->listen_sslctx, + worker->daemon->tcl, worker->daemon->listen_dot_sslctx, + worker->daemon->listen_doh_sslctx, + worker->daemon->listen_quic_sslctx, dtenv, worker->daemon->doq_table, worker->env.rnd, - cfg->ssl_service_key, cfg->ssl_service_pem, cfg, - worker_handle_request, worker); + cfg, worker_handle_request, worker); if(!worker->front) { log_err("could not create listening sockets"); worker_delete(worker); @@ -2191,7 +2281,7 @@ worker_init(struct worker* worker, struct config_file *cfg, cfg->unwanted_threshold, cfg->outgoing_tcp_mss, &worker_alloc_cleanup, worker, cfg->do_udp || cfg->udp_upstream_without_downstream, - worker->daemon->connect_sslctx, cfg->delay_close, + worker->daemon->connect_dot_sslctx, cfg->delay_close, cfg->tls_use_sni, dtenv, cfg->udp_connect, cfg->max_reuse_tcp_queries, cfg->tcp_reuse_timeout, cfg->tcp_auth_query_timeout); diff --git a/daemon/worker.h b/daemon/worker.h index ab2fc728d274..b7bb52fd715b 100644 --- a/daemon/worker.h +++ b/daemon/worker.h @@ -72,7 +72,13 @@ enum worker_commands { /** obtain statistics without statsclear */ worker_cmd_stats_noreset, /** execute remote control command */ - worker_cmd_remote + worker_cmd_remote, + /** for fast-reload, perform stop */ + worker_cmd_reload_stop, + /** for fast-reload, start again */ + worker_cmd_reload_start, + /** for fast-reload, poll to make sure worker has released data */ + worker_cmd_reload_poll }; /** diff --git a/dns64/dns64.c b/dns64/dns64.c index 0db174ba95a7..f028cd28aa24 100644 --- a/dns64/dns64.c +++ b/dns64/dns64.c @@ -658,7 +658,8 @@ handle_event_moddone(struct module_qstate* qstate, int id) !dns_cache_store( qstate->env, &qstate->qinfo, qstate->return_msg->rep, 0, qstate->prefetch_leeway, 0, NULL, - qstate->query_flags, qstate->qstarttime)) + qstate->query_flags, qstate->qstarttime, + qstate->is_valrec)) log_err("out of memory"); /* do nothing */ @@ -1008,7 +1009,8 @@ dns64_inform_super(struct module_qstate* qstate, int id, /* Store the generated response in cache. */ if ( (!super_dq || !super_dq->started_no_cache_store) && !dns_cache_store(super->env, &super->qinfo, super->return_msg->rep, - 0, super->prefetch_leeway, 0, NULL, super->query_flags, qstate->qstarttime)) + 0, super->prefetch_leeway, 0, NULL, super->query_flags, + qstate->qstarttime, qstate->is_valrec)) log_err("out of memory"); } diff --git a/dnstap/dnstap.c b/dnstap/dnstap.c index cff308f93164..071fd0895fe6 100644 --- a/dnstap/dnstap.c +++ b/dnstap/dnstap.c @@ -192,8 +192,11 @@ static void dt_apply_identity(struct dt_env *env, struct config_file *cfg) { char buf[MAXHOSTNAMELEN+1]; - if (!cfg->dnstap_send_identity) + if (!cfg->dnstap_send_identity) { + free(env->identity); + env->identity = NULL; return; + } free(env->identity); if (cfg->dnstap_identity == NULL || cfg->dnstap_identity[0] == 0) { if (gethostname(buf, MAXHOSTNAMELEN) == 0) { @@ -215,8 +218,11 @@ dt_apply_identity(struct dt_env *env, struct config_file *cfg) static void dt_apply_version(struct dt_env *env, struct config_file *cfg) { - if (!cfg->dnstap_send_version) + if (!cfg->dnstap_send_version) { + free(env->version); + env->version = NULL; return; + } free(env->version); if (cfg->dnstap_version == NULL || cfg->dnstap_version[0] == 0) env->version = strdup(PACKAGE_STRING); @@ -230,13 +236,8 @@ dt_apply_version(struct dt_env *env, struct config_file *cfg) } void -dt_apply_cfg(struct dt_env *env, struct config_file *cfg) +dt_apply_logcfg(struct dt_env *env, struct config_file *cfg) { - if (!cfg->dnstap) - return; - - dt_apply_identity(env, cfg); - dt_apply_version(env, cfg); if ((env->log_resolver_query_messages = (unsigned int) cfg->dnstap_log_resolver_query_messages)) { @@ -275,6 +276,17 @@ dt_apply_cfg(struct dt_env *env, struct config_file *cfg) lock_basic_unlock(&env->sample_lock); } +void +dt_apply_cfg(struct dt_env *env, struct config_file *cfg) +{ + if (!cfg->dnstap) + return; + + dt_apply_identity(env, cfg); + dt_apply_version(env, cfg); + dt_apply_logcfg(env, cfg); +} + int dt_init(struct dt_env *env, struct comm_base* base) { diff --git a/dnstap/dnstap.h b/dnstap/dnstap.h index 21c033697da1..4390a9cf1591 100644 --- a/dnstap/dnstap.h +++ b/dnstap/dnstap.h @@ -107,6 +107,13 @@ void dt_apply_cfg(struct dt_env *env, struct config_file *cfg); /** + * Apply config settings for log enable for message types. + * @param env: dnstap environment object. + * @param cfg: new config settings. + */ +void dt_apply_logcfg(struct dt_env *env, struct config_file *cfg); + +/** * Initialize per-worker state in dnstap environment object. * @param env: dnstap environment object to initialize, created with dt_create(). * @param base: event base for wakeup timer. diff --git a/dnstap/unbound-dnstap-socket.c b/dnstap/unbound-dnstap-socket.c index 7f8be4965957..a01627de9650 100644 --- a/dnstap/unbound-dnstap-socket.c +++ b/dnstap/unbound-dnstap-socket.c @@ -346,7 +346,8 @@ static struct tap_socket* tap_socket_new_tlsaccept(char* ip, s->fd = -1; s->ev_cb = ev_cb; s->data = data; - s->sslctx = listen_sslctx_create(server_key, server_cert, verifypem); + s->sslctx = listen_sslctx_create(server_key, server_cert, verifypem, + NULL, NULL, 0, 0, 0); if(!s->sslctx) { log_err("could not create ssl context"); free(s->ip); @@ -1786,6 +1787,20 @@ void remote_get_opt_ssl(char* ATTR_UNUSED(str), void* ATTR_UNUSED(arg)) log_assert(0); } +void fast_reload_service_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), + void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} + +int fast_reload_client_callback(struct comm_point* ATTR_UNUSED(c), + void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), + struct comm_reply* ATTR_UNUSED(repinfo)) +{ + log_assert(0); + return 0; +} + #ifdef HAVE_NGTCP2 void doq_client_event_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), void* ATTR_UNUSED(arg)) diff --git a/doc/Changelog b/doc/Changelog index fde05db51292..9668a6364cf4 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,9 +1,273 @@ +11 April 2025: Yorgos + - Merge #1265: Fix WSAPoll. + +10 April 2025: Wouter + - Fix for print of connection type in log-replies for dot and doh. + +9 April 2025: Wouter + - Fix to detect if atomic_store links in configure. + - Fix #1264: unbound 1.22.0 leaks memory when doing DoH. + +8 April 2025: Wouter + - Tag for 1.23.0rc1. + - Fix fast_reload to print chroot with config file name. + +7 April 2025: Yorgos + - Merge #902: DNS Error Reporting (RFC 9567). Introduces new + configuration option 'dns-error-reporting' and new statistics for + 'num.dns_error_reports'. + +4 April 2025: Wouter + - Fix mesh_copy_client_info to omit null contents from copy. + - Fix comment name in the rpz nsdname test. + - Fix nettle compile for warnings and ticket keys. + - Fix redis_replica test for unused option defaults and log printout. + - Fix test to speed up common.sh script kill_pid. + - Fix to update common.sh for speed of kill_pid. + +4 April 2025: Yorgos + - Merge #1019: Redis read-only replica support. + Introduces new 'redis-replica-*' options for the Redis cache backend. + +3 April 2025: Wouter + - Fix #1263: Exempt loopback addresses from wait-limit. + - Fix wait-limit-netblock and wait-limit-cookie-netblock config parse + to allow two arguments. + - Fix ub_event and include dnstap and win_svc headers. + - Fix test for stat_values for wait limit defaults for localhost. + - Fix parameter unused warning in net_help.c. + +2 April 2025: Yorgos + - Merge #1262 from markyang92, fix build with + 'gcc-15 -Wbuiltin-declaration-mismatch' error in compat/malloc.c. + - For #1262, ifdef is no longer needed. + +2 April 2025: Wouter + - Fix unbound-control test so it counts the new flush_negative output, + also answers the _ta probe from testns and prints command output + and skip a thread specific test when no threads are available. + - Fix that ub_event has the facility to deal with callbacks for + fast reload, doq, windows-stop and dnstap. + - Fix fast reload test to check if pid exists before acting on it. + +1 April 2025: Wouter + - Fix escape more characters when printing an RR type with an unquoted + string. + - Enable the auth_tls.tdir and auth_tls_failcert.tdir tests. + +31 March 2025: Wouter + - iana portlist update. + - Merge #1042: Fast Reload. The unbound-control fast_reload is added. + It reads changed config in a thread, then only briefly pauses the + service threads, that keep running. DNS service is only interrupted + briefly, less than a second. + - Skip the unit tests for auth_tls.tdir and auth_tls_failcert.tdir. + +27 March 2025: Wouter + - Fix unit test dname log printout typecast. + - Fix for ci test, expat is installed on the osx image. + +26 March 2025: Yorgos + - Fix #1255: Multiple pinnings to vulnerable copies of libexpat. + - For #1255, for ios use an older expat version that does not require + C++11 language features. + - For #1255, for ios disable building tests that require C++11. + - For #1255, for ios try the latest expat version again. + +24 March 2025: Wouter + - Fix #1254: `send failed: Socket is not connected` and + `remote address is 0.0.0.0 port 53`. + +21 March 2025: Wouter + - Fix #1253: Cache entries fail to be removed from Redis cachedb + backend with unbound-control flush* +c. + - Fix for #1253: Fix for redis cachedb backend to expect an integer + reply for the EXPIRE command. + +20 March 2025: Wouter + - Fix print of RR type NSAP-PTR, it is an unquoted string. + +18 March 2025: Wouter + - Fix #1251: WSAPoll first argument cannot be NULL. + - Fix for windows compile create ssl contexts. + +17 March 2025: Wouter + - Fix representation of types GPOS and RESINFO, add rdf type for + unquoted str. + +16 March 2025: Yorgos + - Fix 'unbound-control flush_negative' when reporting removed data; + reported by David 'eqvinox' Lamparter. + +28 February 2025: Wouter + - Merge #1238: Prefer SOURCE_DATE_EPOCH over actual time. + Add --help output description for the SOURCE_DATE_EPOCH variable. + +25 February 2025: Wouter + - Merge #1243: Do not shadow tm on line 236. + +24 February 2025: Yorgos + - Fix hash calculation for cachedb to ignore case. Previously, cached + records there were only relevant for same case queries (if not + already in Unbound's internal cache). + +19 February 2025: Yorgos + - Fix static analysis report about unhandled EOF on error conditions + when reading anchor key files. + - Merge #1241: Fix infra-keep-probing for low infra-cache-max-rtt + values. + +17 February 2025: Yorgos + - Consider reconfigurations when calculating the still_useful_timeout + for servers in the infrastructure cache. + +30 January 2025: Wouter + - Fix #986: Resolving sas.com with dnssec-validation fails though + signed delegations seem to be (mostly) correct. + +29 January 2025: Yorgos + - Make the default value of module-config "validator iterator" + regardless of compilation options. --enable-subnet would implicitly + change the value to enable the subnetcache module by default in the + past. + +24 January 2025: Yorgos + - Merge #1220 from Petr MenÅ¡Ãk, Add unbound members group access to + control key. + +21 January 2025: Yorgos + - Use the same interface listening port discovery code for all needed + protocols. + - Port to string only when needed before getaddrinfo(). + - Do not open unencrypted channels next to encrypted ones on the same + port. + - Merge #1224 from Theo Buehler: Do not use DSA API unless USE_DSA is + set. + +21 January 2025: Wouter + - Fix compile of interface check code when dnscrypt or quic is + disabled. + - Fix encoding of RR type ATMA. + - Fix to check length in ATMA string to wire. + - Merge #1229: check before use daemon->shm_info. + +20 January 2025: Yorgos + - Merge #1222: Unique DoT and DoH SSL contexts to allow for different + ALPN. + - Create the quic SSL listening context only when needed. + +15 January 2025: Yorgos + - Merge #1221: Consider auth zones when checking for forwarders. + +14 January 2025: Yorgos + - Add resolver.arpa and service.arpa to the default locally served + zones. + +13 January 2025: Yorgos + - Fix #1213: Misleading error message on default access control causing + refuse. + +10 January 2025: Yorgos + - Merge #1214: Use TCP_NODELAY on TLS sockets to speed up the TLS + handshake. + +31 December 2024: Yorgos + - Merge #1174: Serve expired cache update fixes. Fixes a regression bug + with serve-expired that appeared in 1.22.0 and would not allow the + iterator to update the cache with not-yet-validated entries resulting + in increased outgoing traffic. + +20 December 2024: Yorgos + - For #1207: [FR] Support for RESINFO RRType 261 (RFC9606), add + LDNS_RR_TYPE_RESINFO similar to LDNS_RR_TYPE_TXT. + +13 December 2024: Yorgos + - Merge #1204: ci: set persist-credentials: false for actions/checkout + per zizmor suggestion. + +3 December 2024: Yorgos + - Merge #1189: Fix the dname_str method to cause conversion errors + when the domain name length is 255. + - Merge #1197: dname_str() fixes. + - For #1175, the default value of serve-expired-ttl is set to 86400 + (1 day) as suggested by RFC8767. + - Merge #1198: Fix log-servfail with serve expired and no useful cache + contents. + - Safeguard alias loop while looking in the cache for expired answers. + - Merge #1187: Create the SSL_CTX for QUIC before chroot and privilege + drop. + - Fix typo in log_servfail.tdir test. + +22 November 2024: Yorgos + - Fix #1175: serve-expired does not adhere to secure-by-default + principle. The default value of serve-expired-client-timeout + is set to 1800 as suggested by RFC8767. + - For #1175, update serve-expired tests. + +20 November 2024: Yorgos + - Fix comparison to help static analyzer. + +19 November 2024: Yorgos + - Merge #1169 from Sergey Kacheev, fix: lock-free counters for + auth_zone up/down queries. + +15 November 2024: Wouter + - Fix #1183: the data being used is released in method + nsec3_hash_test_entry. + - Fix for #1183: release nsec3 hashes per test file. + +8 November 2024: Yorgos + - More descriptive text for 'harden-algo-downgrade'. + - Complete fix for max-global-quota to 200. + +6 November 2024: Yorgos + - Increase the default of max-global-quota to 200 from 128 after + operational feedback. Still keeping the possible amplification + factor (CAMP related issues) in the hundreds. + +5 November 2024: Wouter + - Fix for the serve expired DNSSEC information fix, it would not allow + current delegation information be updated in cache. The fix allows + current delegation and validation recursion information to be + updated, but as a consequence no longer has certain expired + information around for later dnssec valid expired responses. + - Fix to log redis timeout error string on failure. + +5 November 2024: Yorgos + - Fix SETEX check during Redis (re)initialization. + +4 November 2024: Wouter + - Fix redis that during a reload it does not fail if the redis + server does not connect or does not respond. It still logs the + errors and if the server is up checks expiration features. + - Merge #1167: Makefile.in: fix occasional parallel build failures + around bison rule. + +1 November 2024: Yorgos + - Merge #1159: Stats for discard-timeout and wait-limit. + - Add test case for #1159. + - Some clean up for stat_values.test. + - Merge #1170 from Melroy van den Berg, Fix chroot manpage + description. + - Merge #1157 from Liang Zhu, Fix heap corruption when calling + ub_ctx_delete in Windows. + +25 October 2024: Yorgos + - Fix #1163: Typos in unbound.conf documentation. + +17 October 2024: Wouter + - Tag for 1.22.0 release. This did not contain the 1154 fix + from 16 oct. The code repository continues with + version 1.22.1 in development. + 16 October 2024: Yorgos - Fix for dnsoverquic and dnstap to use the correct dnstap environment. 16 October 2024: Wouter - Fix for dnstap with dnscrypt and dnstap without dnsoverquic. + - Fix #1154: Tag Incorrectly Applying for Other Interfaces + Using the Same IP. This fix is not for 1.22.0. 14 October 2024: Wouter - Fix to display warning if quic-port is set but dnsoverquic is not @@ -23,6 +287,7 @@ - Fix add reallocarray to alloc stats unit test, and disable override of strdup in unbound-host, and the result of config get option is freed properly. + - Tag for 1.22.0rc1. 9 October 2024: Wouter - Merge #871: DNS over QUIC. This adds `quic-port: 853` and diff --git a/doc/README b/doc/README index 600f0feb2fa7..50d9022dbdca 100644 --- a/doc/README +++ b/doc/README @@ -1,4 +1,4 @@ -README for Unbound 1.22.0 +README for Unbound 1.23.0 Copyright 2007 NLnet Labs http://unbound.net diff --git a/doc/example.conf.in b/doc/example.conf.in index 59090c6bb5d5..ba817288bb62 100644 --- a/doc/example.conf.in +++ b/doc/example.conf.in @@ -1,7 +1,7 @@ # # Example configuration file. # -# See unbound.conf(5) man page, version 1.22.0. +# See unbound.conf(5) man page, version 1.23.0. # # this is a comment. @@ -194,7 +194,7 @@ server: # iter-scrub-cname: 11 # Limit on upstream queries for an incoming query and its recursion. - # max-global-quota: 128 + # max-global-quota: 200 # msec for waiting for an unknown server to reply. Increase if you # are behind a slow satellite link, to eg. 1128. @@ -215,6 +215,12 @@ server: # Apart from the default, the wait limit with cookie can be adjusted. # wait-limit-cookie-netblock: 192.0.2.0/24 50000 + # Defaults for loopback, it has no wait limit. + # wait-limit-netblock: 127.0.0.0/8 -1 + # wait-limit-netblock: ::1/128 -1 + # wait-limit-cookie-netblock: 127.0.0.0/8 -1 + # wait-limit-cookie-netblock: ::1/128 -1 + # the amount of memory to use for the RRset cache. # plain value in bytes or you can append k, m or G. default is "4Mb". # rrset-cache-size: 4m @@ -556,8 +562,9 @@ server: # harden-referral-path: no # Harden against algorithm downgrade when multiple algorithms are - # advertised in the DS record. If no, allows the weakest algorithm - # to validate the zone. + # advertised in the DS record. If no, allows any algorithm + # to validate the zone which is the standard behavior for validators. + # Check the manpage for detailed information. # harden-algo-downgrade: no # Harden against unknown records in the authority section and the @@ -730,12 +737,13 @@ server: # disable-edns-do: no # Serve expired responses from cache, with serve-expired-reply-ttl in - # the response, and then attempt to fetch the data afresh. + # the response. By default it first tries to refresh an expired answer. + # Can be configured with serve-expired-client-timeout. # serve-expired: no # # Limit serving of expired responses to configured seconds after # expiration. 0 disables the limit. - # serve-expired-ttl: 0 + # serve-expired-ttl: 86400 # # Set the TTL of expired records to the serve-expired-ttl value after a # failed attempt to retrieve the record from upstream. This makes sure @@ -748,10 +756,9 @@ server: # # Time in milliseconds before replying to the client with expired data. # This essentially enables the serve-stale behavior as specified in - # RFC 8767 that first tries to resolve before - # immediately responding with expired data. 0 disables this behavior. - # A recommended value is 1800. - # serve-expired-client-timeout: 0 + # RFC 8767 that first tries to resolve before immediately responding + # with expired data. 0 disables this behavior. + # serve-expired-client-timeout: 1800 # Return the original TTL as received from the upstream name server rather # than the decrementing TTL as stored in the cache. Enabling this feature @@ -810,6 +817,8 @@ server: # local-zone: "127.in-addr.arpa." nodefault # local-zone: "1.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.0.ip6.arpa." nodefault # local-zone: "home.arpa." nodefault + # local-zone: "resolver.arpa." nodefault + # local-zone: "service.arpa." nodefault # local-zone: "onion." nodefault # local-zone: "test." nodefault # local-zone: "invalid." nodefault @@ -1077,6 +1086,11 @@ server: # Note that the ede option above needs to be enabled for this to work. # ede-serve-expired: no + # Enable DNS Error Reporting (RFC9567). + # qname-minimisation is advised to be turned on as well to increase + # privacy on the outgoing reports. + # dns-error-reporting: no + # Specific options for ipsecmod. Unbound needs to be configured with # --enable-ipsecmod for these to take effect. # @@ -1304,9 +1318,9 @@ remote-control: # # redis server's TCP port # redis-server-port: 6379 # # if the server uses a unix socket, set its path, or "" when not used. -# # redis-server-path: "/var/lib/redis/redis-server.sock" +# redis-server-path: "/var/lib/redis/redis-server.sock" # # if the server uses an AUTH password, specify here, or "" when not used. -# # redis-server-password: "" +# redis-server-password: "" # # timeout (in ms) for communication with the redis server # redis-timeout: 100 # # timeout (in ms) for commands, if 0, uses redis-timeout. @@ -1317,6 +1331,22 @@ remote-control: # redis-expire-records: no # # redis logical database to use, 0 is the default database. # redis-logical-db: 0 +# # redis replica server's IP address or host name +# redis-replica-server-host: 127.0.0.1 +# # redis replica server's TCP port +# redis-replica-server-port: 6379 +# # if the replica server uses a unix socket, set its path, or "" when not used. +# redis-replica-server-path: "/var/lib/redis/redis-server.sock" +# # if the replica server uses an AUTH password, specify here, or "" when not used. +# redis-replica-server-password: "" +# # timeout (in ms) for communication with the redis replica server +# redis-replica-timeout: 100 +# # timeout (in ms) for redis replica commands, if 0, uses redis-replica-timeout. +# redis-replica-command-timeout: 0 +# # timeout (in ms) for redis replica connection set up, if 0, uses redis-replica-timeout. +# redis-replica-connect-timeout: 0 +# # redis logical database to use for the replica server, 0 is the default database. +# redis-replica-logical-db: 0 # IPSet # Add specify domain into set via ipset. diff --git a/doc/libunbound.3.in b/doc/libunbound.3.in index bb2a5c26945a..4edc9b3c30af 100644 --- a/doc/libunbound.3.in +++ b/doc/libunbound.3.in @@ -1,4 +1,4 @@ -.TH "libunbound" "3" "Oct 17, 2024" "NLnet Labs" "unbound 1.22.0" +.TH "libunbound" "3" "Apr 24, 2025" "NLnet Labs" "unbound 1.23.0" .\" .\" libunbound.3 -- unbound library functions manual .\" @@ -44,7 +44,7 @@ .B ub_ctx_zone_remove, .B ub_ctx_data_add, .B ub_ctx_data_remove -\- Unbound DNS validating resolver 1.22.0 functions. +\- Unbound DNS validating resolver 1.23.0 functions. .SH "SYNOPSIS" .B #include <unbound.h> .LP diff --git a/doc/unbound-anchor.8.in b/doc/unbound-anchor.8.in index 66e69cc9c352..c3a8d64cabbe 100644 --- a/doc/unbound-anchor.8.in +++ b/doc/unbound-anchor.8.in @@ -1,4 +1,4 @@ -.TH "unbound-anchor" "8" "Oct 17, 2024" "NLnet Labs" "unbound 1.22.0" +.TH "unbound-anchor" "8" "Apr 24, 2025" "NLnet Labs" "unbound 1.23.0" .\" .\" unbound-anchor.8 -- unbound anchor maintenance utility manual .\" diff --git a/doc/unbound-checkconf.8.in b/doc/unbound-checkconf.8.in index ac657d83089c..73cb0ebcbb5f 100644 --- a/doc/unbound-checkconf.8.in +++ b/doc/unbound-checkconf.8.in @@ -1,4 +1,4 @@ -.TH "unbound-checkconf" "8" "Oct 17, 2024" "NLnet Labs" "unbound 1.22.0" +.TH "unbound-checkconf" "8" "Apr 24, 2025" "NLnet Labs" "unbound 1.23.0" .\" .\" unbound-checkconf.8 -- unbound configuration checker manual .\" diff --git a/doc/unbound-control.8.in b/doc/unbound-control.8.in index 7016e8f12515..449c279d6499 100644 --- a/doc/unbound-control.8.in +++ b/doc/unbound-control.8.in @@ -1,4 +1,4 @@ -.TH "unbound-control" "8" "Oct 17, 2024" "NLnet Labs" "unbound 1.22.0" +.TH "unbound-control" "8" "Apr 24, 2025" "NLnet Labs" "unbound 1.23.0" .\" .\" unbound-control.8 -- unbound remote control manual .\" @@ -60,6 +60,155 @@ Reload the server but try to keep the RRset and message cache if That means the caches sizes and the number of threads must not change between reloads. .TP +.B fast_reload \fR[\fI+dpv\fR] +Reload the server, but keep downtime to a minimum, so that user queries +keep seeing service. This needs the code compiled with threads. The config +is loaded in a thread, and prepared, then it briefly pauses the existing +server and updates config options. The intent is that the pause does not +impact the service of user queries. The cache is kept. Also user queries +worked on are kept and continue, but with the new config options. +.IP +This command is experimental at this time. +.IP +The amount of temporal memory needed during a fast_reload is twice the +amount needed for configuration. +This is because Unbound temporarily needs to store both current configuration +values and new ones while trying to fast_reload. +Zones loaded from disk (authority zones and RPZ zones) are included in such +memory needs. +.IP +Options that can be changed are for +forwards, +stubs, +views, +authority zones, +RPZ zones and +local zones. +.IP +Also +access-control and similar options, +interface-action and similar options and +tcp-connection-limit. +It can reload some +define-tag +changes, more on that below. +Further options include +insecure-lan-zones, +domain-insecure, +trust-anchor-file, +trust-anchor, +trusted-keys-file, +auto-trust-anchor-file, +edns-client-string, +ipset, +log-identity, +infra-cache-numhosts, +msg-cache-size, +rrset-cache-size, +key-cache-size, +ratelimit-size, +neg-cache-size, +num-queries-per-thread, +jostle-timeout, +use-caps-for-id, +unwanted-reply-threshold, +tls-use-sni, +outgoing-tcp-mss, +ip-dscp, +max-reuse-tcp-queries, +tcp-reuse-timeout, +tcp-auth-query-timeout, +delay-close. +.IP +It does not work with +interface and +outgoing-interface changes, +also not with +remote control, +outgoing-port-permit, +outgoing-port-avoid, +msg-buffer-size, +any **\*-slabs** options and +statistics-interval changes. +.IP +For dnstap these options can be changed: +dnstap-log-resolver-query-messages, +dnstap-log-resolver-response-messages, +dnstap-log-client-query-messages, +dnstap-log-client-response-messages, +dnstap-log-forwarder-query-messages and +dnstap-log-forwarder-response-messages. +.IP +It does not work with these options: +dnstap-enable, +dnstap-bidirectional, +dnstap-socket-path, +dnstap-ip, +dnstap-tls, +dnstap-tls-server-name, +dnstap-tls-cert-bundle, +dnstap-tls-client-key-file and +dnstap-tls-client-cert-file. +.IP +The options +dnstap-send-identity, +dnstap-send-version, +dnstap-identity, and +dnstap-version can be loaded +when ``+p`` is not used. +.IP +The '+v' option makes the output verbose which includes the time it took to do +the reload. +With '+vv' it is more verbose which includes the amount of memory that was +allocated temporarily to perform the reload; this amount of memory can be big +if the config has large contents. +In the timing output the 'reload' time is the time during which the server was +paused. +.IP +The '+p' option makes the reload not pause threads, they keep running. +Locks are acquired, but items are updated in sequence, so it is possible +for threads to see an inconsistent state with some options from the old +and some options from the new config, such as cache TTL parameters from the +old config and forwards from the new config. The stubs and forwards are +updated at the same time, so that they are viewed consistently, either old +or new values together. The option makes the reload time take eg. 3 +microseconds instead of 0.3 milliseconds during which the worker threads are +interrupted. So, the interruption is much shorter, at the expense of some +inconsistency. After the reload itself, every worker thread is briefly +contacted to make them release resources, this makes the delete timing +a little longer, and takes up time from the remote control servicing +worker thread. +.IP +With the nopause option, the reload does not work to reload some options, +that fast reload works on without the nopause option: val-bogus-ttl, +val-override-date, val-sig-skew-min, val-sig-skew-max, val-max-restart, +val-nsec3-keysize-iterations, target-fetch-policy, outbound-msg-retry, +max-sent-count, max-query-restarts, do-not-query-address, +do-not-query-localhost, private-address, private-domain, caps-exempt, +nat64-prefix, do-nat64, infra-host-ttl, infra-keep-probing, ratelimit, +ip-ratelimit, ip-ratelimit-cookie, wait-limit-netblock, +wait-limit-cookie-netblock, ratelimit-below-domain, ratelimit-for-domain. +.IP +The '+d' option makes the reload drop queries that the worker threads are +working on. This is like flush_requestlist. Without it the queries are kept +so that users keep getting answers for those queries that are currently +processed. The drop makes it so that queries during the life time of the +query processing see only old, or only new config options. +.IP +When there are changes to the config tags, from the \fBdefine\-tag\fR option, +then the '+d' option is implicitly turned on with a warning printout, and +queries are dropped. +This is to stop references to the old tag information, by the old +queries. If the number of tags is increased in the newly loaded config, by +adding tags at the end, then the implicit '+d' option is not needed. +.IP +For response ip, that is actions associated with IP addresses, and perhaps +intersected with access control tag and action information, those settings +are stored with a query when it comes in based on its source IP address. +The old information is kept with the query until the queries are done. +This is gone when those queries are resolved and finished, or it is possible +to flush the requestlist with '+d'. +.TP .B verbosity \fInumber Change verbosity value for logging. Same values as \fBverbosity\fR keyword in \fIunbound.conf\fR(5). This new setting lasts until the server is issued @@ -422,6 +571,12 @@ number of queries with a client part only DNS Cookie by thread .I threadX.num.queries_cookie_invalid number of queries with an invalid DNS Cookie by thread .TP +.I threadX.num.queries_discard_timeout +number of queries removed due to discard-timeout by thread +.TP +.I threadX.num.queries_wait_limit +number of queries removed due to wait-limit by thread +.TP .I threadX.num.cachehits number of queries that were successfully answered using a cache lookup .TP @@ -441,6 +596,9 @@ request for certificates. .I threadX.num.dnscrypt.malformed number of request that were neither cleartext, not valid dnscrypt messages. .TP +.I threadX.num.dns_error_reports +number of DNS Error Reports generated by thread +.TP .I threadX.num.prefetch number of cache prefetches performed. This number is included in cachehits, as the original query had the unprefetched answer from cache, @@ -511,6 +669,12 @@ summed over threads. .I total.num.queries_cookie_invalid summed over threads. .TP +.I total.num.queries_discard_timeout +summed over threads. +.TP +.I total.num.queries_wait_limit +summed over threads. +.TP .I total.num.cachehits summed over threads. .TP @@ -529,6 +693,9 @@ summed over threads. .I total.num.dnscrypt.malformed summed over threads. .TP +.I total.num.dns_error_reports +summed over threads. +.TP .I total.num.prefetch summed over threads. .TP diff --git a/doc/unbound-host.1.in b/doc/unbound-host.1.in index 1bd6ff54e4c0..f56a8d4d18ed 100644 --- a/doc/unbound-host.1.in +++ b/doc/unbound-host.1.in @@ -1,4 +1,4 @@ -.TH "unbound\-host" "1" "Oct 17, 2024" "NLnet Labs" "unbound 1.22.0" +.TH "unbound\-host" "1" "Apr 24, 2025" "NLnet Labs" "unbound 1.23.0" .\" .\" unbound-host.1 -- unbound DNS lookup utility .\" diff --git a/doc/unbound.8.in b/doc/unbound.8.in index 51986eb857e1..33c87cde4edf 100644 --- a/doc/unbound.8.in +++ b/doc/unbound.8.in @@ -1,4 +1,4 @@ -.TH "unbound" "8" "Oct 17, 2024" "NLnet Labs" "unbound 1.22.0" +.TH "unbound" "8" "Apr 24, 2025" "NLnet Labs" "unbound 1.23.0" .\" .\" unbound.8 -- unbound manual .\" @@ -9,7 +9,7 @@ .\" .SH "NAME" .B unbound -\- Unbound DNS validating resolver 1.22.0. +\- Unbound DNS validating resolver 1.23.0. .SH "SYNOPSIS" .B unbound .RB [ \-h ] diff --git a/doc/unbound.conf.5.in b/doc/unbound.conf.5.in index 536474349982..4484267dbc79 100644 --- a/doc/unbound.conf.5.in +++ b/doc/unbound.conf.5.in @@ -1,4 +1,4 @@ -.TH "unbound.conf" "5" "Oct 17, 2024" "NLnet Labs" "unbound 1.22.0" +.TH "unbound.conf" "5" "Apr 24, 2025" "NLnet Labs" "unbound 1.23.0" .\" .\" unbound.conf.5 -- unbound.conf manual .\" @@ -326,11 +326,15 @@ The wait limit for the netblock. If not given the wait\-limit value is used. The most specific netblock is used to determine the limit. Useful for overriding the default for a specific, group or individual, server. The value -1 disables wait limits for the netblock. +By default the loopback has a wait limit netblock of -1, it is not limited, +because it is separated from the rest of network for spoofed packets. +The loopback addresses 127.0.0.0/8 and ::1/128 are default at -1. .TP .B wait\-limit\-cookie\-netblock: \fI<netblock> <number> The wait limit for the netblock, when the query has a DNS cookie. If not given, the wait\-limit\-cookie value is used. The value -1 disables wait limits for the netblock. +The loopback addresses 127.0.0.0/8 and ::1/128 are default at -1. .TP .B so\-rcvbuf: \fI<number> If not 0, then set the SO_RCVBUF socket option to get more buffer @@ -716,7 +720,7 @@ and initial ACL (check if the proxy itself is denied/refused by configuration). The proxied address (if any) will then be used as the true client address and will be used where applicable for logging, ACL, DNSTAP, RPZ and IP ratelimiting. PROXYv2 is supported for UDP and TCP/TLS listening interfaces. -There is no support for PROXYv2 on a DoH or DNSCrypt listening interface. +There is no support for PROXYv2 on a DoH, DoQ or DNSCrypt listening interface. Can list multiple, each on a new statement. .TP .B quic\-port: \fI<number> @@ -902,9 +906,8 @@ outside of the chroot directory. Additionally, Unbound may need to access /dev/urandom (for entropy) from inside the chroot. .IP -If given a chroot is done to the given directory. By default chroot is -enabled and the default is "@UNBOUND_CHROOT_DIR@". If you give "" no -chroot is performed. +If given a chroot is done to the given directory. The chroot is by default +set to "@UNBOUND_CHROOT_DIR@". If you give "" no chroot is performed. .TP .B username: \fI<name> If given, after binding the port the user privileges are dropped. Default is @@ -1056,11 +1059,11 @@ closer to that of BIND 9, while setting "\-1 \-1 \-1 \-1 \-1" gives behaviour rumoured to be closer to that of BIND 8. .TP .B harden\-short\-bufsize: \fI<yes or no> -Very small EDNS buffer sizes from queries are ignored. Default is on, as +Very small EDNS buffer sizes from queries are ignored. Default is yes, as described in the standard. .TP .B harden\-large\-queries: \fI<yes or no> -Very large queries are ignored. Default is off, since it is legal protocol +Very large queries are ignored. Default is no, since it is legal protocol wise to send these, and could be necessary for operation if TSIG or EDNS payload is very large. .TP @@ -1107,10 +1110,23 @@ to increase the max depth that is checked to. .TP .B harden\-algo\-downgrade: \fI<yes or no> Harden against algorithm downgrade when multiple algorithms are -advertised in the DS record. If no, allows the weakest algorithm to -validate the zone. Default is no. Zone signers must produce zones -that allow this feature to work, but sometimes they do not, and turning -this option off avoids that validation failure. +advertised in the DS record. +This works by first choosing only the strongest DS digest type as per RFC 4509 +(Unbound treats the highest algorithm as the strongest) and then +expecting signatures from all the advertised signing algorithms from the chosen +DS(es) to be present. +If no, allows any one supported algorithm to validate the zone, even if other advertised algorithms are broken. +Default is no. +RFC 6840 mandates that zone signers must produce zones signed with all +advertised algorithms, but sometimes they do not. +RFC 6840 also clarifies that this requirement is not for validators and +validators should accept any single valid path. +It should thus be explicitly noted that this option violates RFC 6840 for +DNSSEC validation and should only be used to perform a signature +completeness test to support troubleshooting. +Using this option may break DNSSEC resolution with non-RFC6840-conforming +signers and/or in multi-signer configurations that don't send all the +advertised signatures. .TP .B harden\-unknown\-additional: \fI<yes or no> Harden against unknown records in the authority section and additional @@ -1131,7 +1147,7 @@ queries. For domains that do not support 0x20 and also fail with fallback because they keep sending different answers, like some load balancers. Can be given multiple times, for different domains. .TP -.B caps\-whitelist: \fI<yes or no> +.B caps\-whitelist: \fI<domain> Alternate syntax for \fBcaps\-exempt\fR. .TP .B qname\-minimisation: \fI<yes or no> @@ -1248,9 +1264,6 @@ Adding \fIrespip\fR to the front will cause RPZ processing to be done on all queries. The default is "\fIvalidator iterator\fR". .IP -When the server is built with -EDNS client subnet support the default is "\fIsubnetcache validator -iterator\fR". Most modules that need to be listed here have to be listed at the beginning of the line. The subnetcachedb module has to be listed just before the iterator. @@ -1390,15 +1403,17 @@ Default is no. .TP .B serve\-expired: \fI<yes or no> If enabled, Unbound attempts to serve old responses from cache with a -TTL of \fBserve\-expired\-reply\-ttl\fR in the response without waiting for the -actual resolution to finish. The actual resolution answer ends up in the cache -later on. Default is "no". +TTL of \fBserve\-expired\-reply\-ttl\fR in the response. +By default the expired answer will be used after a resolution attempt errored +out or is taking more than serve\-expired\-client\-timeout to resolve. +Default is "no". .TP .B serve\-expired\-ttl: \fI<seconds> -Limit serving of expired responses to configured seconds after expiration. 0 -disables the limit. This option only applies when \fBserve\-expired\fR is -enabled. A suggested value per RFC 8767 is between -86400 (1 day) and 259200 (3 days). The default is 0. +Limit serving of expired responses to configured seconds after expiration. +0 disables the limit. +This option only applies when \fBserve\-expired\fR is enabled. +A suggested value per RFC 8767 is between 86400 (1 day) and 259200 (3 days). +The default is 86400. .TP .B serve\-expired\-ttl\-reset: \fI<yes or no> Set the TTL of expired records to the \fBserve\-expired\-ttl\fR value after a @@ -1412,12 +1427,14 @@ TTL value to use when replying with expired data. If use 30 as the value (RFC 8767). The default is 30. .TP .B serve\-expired\-client\-timeout: \fI<msec> -Time in milliseconds before replying to the client with expired data. This -essentially enables the serve-stale behavior as specified in +Time in milliseconds before replying to the client with expired data. +This essentially enables the serve-stale behavior as specified in RFC 8767 that first tries to resolve before immediately -responding with expired data. A recommended value per -RFC 8767 is 1800. Setting this to 0 will disable this -behavior. Default is 0. +responding with expired data. +Setting this to 0 will disable this behavior and instead serve the expired +record immediately from the cache before attempting to refresh it via +resolution. +Default is 1800. .TP .B serve\-original\-ttl: \fI<yes or no> If enabled, Unbound will always return the original TTL as received from @@ -1622,6 +1639,7 @@ given zone. Use \fInodefault\fR if you use exactly that zone, if you want to use a subzone, use \fItransparent\fR. .P The default zones are localhost, reverse 127.0.0.1 and ::1, the home.arpa, +the resolver.arpa, the service.arpa, the onion, test, invalid and the AS112 zones. The AS112 zones are reverse DNS zones for private use and reserved IP addresses for which the servers on the internet cannot provide correct answers. They are configured by @@ -1677,6 +1695,24 @@ local\-data: "home.arpa. 10800 IN SOA localhost. nobody.invalid. 1 3600 1200 604800 10800" .fi .TP 10 +\h'5'\fIresolver.arpa (RFC 9462)\fR +Default content: +.nf +local\-zone: "resolver.arpa." static +local\-data: "resolver.arpa. 10800 IN NS localhost." +local\-data: "resolver.arpa. 10800 IN + SOA localhost. nobody.invalid. 1 3600 1200 604800 10800" +.fi +.TP 10 +\h'5'\fIservice.arpa (draft-ietf-dnssd-srp-25)\fR +Default content: +.nf +local\-zone: "service.arpa." static +local\-data: "service.arpa. 10800 IN NS localhost." +local\-data: "service.arpa. 10800 IN + SOA localhost. nobody.invalid. 1 3600 1200 604800 10800" +.fi +.TP 10 \h'5'\fIonion (RFC 7686)\fR Default content: .nf @@ -1998,7 +2034,7 @@ Default is 11. Limit on the number of upstream queries sent out for an incoming query and its subqueries from recursion. It is not reset during the resolution. When it is exceeded the query is failed and the lookup process stops. -Default is 128. +Default is 200. .TP 5 .B fast\-server\-permil: \fI<number> Specify how many times out of 1000 to pick from the set of fastest servers. @@ -2053,17 +2089,30 @@ be used. Default is 65001. .TP 5 .B ede: \fI<yes or no> If enabled, Unbound will respond with Extended DNS Error codes (RFC8914). -These EDEs attach informative error messages to a response for various -errors. Default is "no". +These EDEs provide additional information with a response mainly for, but not +limited to, DNS and DNSSEC errors. When the \fBval-log-level\fR option is also set to \fB2\fR, responses with -Extended DNS Errors concerning DNSSEC failures that are not served from cache, -will also contain a descriptive text message about the reason for the failure. +Extended DNS Errors concerning DNSSEC failures will also contain a descriptive +text message about the reason for the failure. +Default is "no". .TP 5 .B ede\-serve\-expired: \fI<yes or no> If enabled, Unbound will attach an Extended DNS Error (RFC8914) Code 3 - Stale -Answer as EDNS0 option to the expired response. Note that this will not attach -the EDE code without setting the global \fBede\fR option to "yes" as well. +Answer as EDNS0 option to the expired response. +The \fBede\fR option needs to be enabled as well for this to work. +Default is "no". +.TP 5 +.B dns\-error\-reporting: \fI<yes or no> +If enabled, Unbound will send DNS Error Reports (RFC9567). +The name servers need to express support by attaching the Report-Channel EDNS0 +option on their replies specifying the reporting agent for the zone. +Any errors encountered during resolution that would result in Unbound +generating an Extended DNS Error (RFC8914) will be reported to the zone's +reporting agent. +The \fBede\fR option does not need to be enabled for this to work. +It is advised that the \fBqname\-minimisation\fR option is also enabled to +increase privacy on the outgoing reports. Default is "no". .SS "Remote Control Options" In the @@ -2476,8 +2525,8 @@ The dynamic library file to load. Repeat this option for every dynlib module instance added to the \fBmodule\-config:\fR option. .SS "DNS64 Module Options" .LP -The dns64 module must be configured in the \fBmodule\-config:\fR "dns64 -validator iterator" directive and be compiled into the daemon to be +The dns64 module must be configured in the \fBmodule\-config:\fR directive +e.g., "dns64 validator iterator" and be compiled into the daemon to be enabled. These settings go in the \fBserver:\fR section. .TP .B dns64\-prefix: \fI<IPv6 prefix>\fR @@ -2577,8 +2626,8 @@ in the dnscrypt nonce cache. Close to the number of cpus is a fairly good setting. .SS "EDNS Client Subnet Module Options" .LP -The ECS module must be configured in the \fBmodule\-config:\fR "subnetcache -validator iterator" directive and be compiled into the daemon to be +The ECS module must be configured in the \fBmodule\-config:\fR directive e.g., +"subnetcache validator iterator" and be compiled into the daemon to be enabled. These settings go in the \fBserver:\fR section. .LP If the destination address is allowed in the configuration Unbound will add the @@ -2599,6 +2648,15 @@ configuration file. On top of that, for each query only 100 different subnets are allowed to be stored for each address family. Exceeding that number, older entries will be purged from cache. .LP +Note that due to the nature of how EDNS Client Subnet works, by segregating the +client IP space in order to try and have tailored responses for prefixes of +unknown sizes, resolution and cache response performance are impacted as a +result. +Usage of the subnetcache module should only be enabled in installations that +require such functionality where the resolver and the clients belong to +different networks. +An example of that is an open resolver installation. +.LP This module does not interact with the \fBserve\-expired*\fR and \fBprefetch:\fR options. .TP @@ -2649,8 +2707,8 @@ Specifies the maximum number of subnets ECS answers kept in the ECS radix tree. This number applies for each qname/qclass/qtype tuple. Defaults to 100. .SS "Opportunistic IPsec Support Module Options" .LP -The IPsec module must be configured in the \fBmodule\-config:\fR "ipsecmod -validator iterator" directive and be compiled into Unbound by using +The IPsec module must be configured in the \fBmodule\-config:\fR directive +e.g., "ipsecmod validator iterator" and be compiled into Unbound by using \fB\-\-enable\-ipsecmod\fR to be enabled. These settings go in the \fBserver:\fR section. .LP @@ -2715,12 +2773,12 @@ Allow the ipsecmod functionality for the domain so that the module logic will be executed. Can be given multiple times, for different domains. If the option is not specified, all domains are treated as being allowed (default). .TP -.B ipsecmod\-whitelist: \fI<yes or no> +.B ipsecmod\-whitelist: \fI<domain> Alternate syntax for \fBipsecmod\-allow\fR. .SS "Cache DB Module Options" .LP -The Cache DB module must be configured in the \fBmodule\-config:\fR -"validator cachedb iterator" directive and be compiled into the daemon +The Cache DB module must be configured in the \fBmodule\-config:\fR directive +e.g., "validator cachedb iterator" and be compiled into the daemon with \fB\-\-enable\-cachedb\fR. If this module is enabled and configured, the specified backend database works as a second level cache: @@ -2815,12 +2873,12 @@ The TCP port number of the Redis server. This option defaults to 6379. .TP .B redis-server-path: \fI<unix socket path>\fR -The unix socket path to connect to the redis server. Off by default, and it +The unix socket path to connect to the Redis server. Off by default, and it can be set to "" to turn this off. Unix sockets may have better throughput than the IP address option. .TP .B redis-server-password: \fI"<password>"\fR -The Redis AUTH password to use for the redis server. +The Redis AUTH password to use for the Redis server. Only relevant if Redis is configured for client password authorisation. Off by default, and it can be set to "" to turn this off. .TP @@ -2832,12 +2890,14 @@ re-establish a new connection later. This option defaults to 100 milliseconds. .TP .B redis-command-timeout: \fI<msec>\fR -The timeout to use for redis commands, in milliseconds. If 0, it uses the -redis\-timeout value. The default is 0. +The timeout to use for Redis commands, in milliseconds. +If 0, it uses the \fBredis\-timeout\fR value. +The default is 0. .TP .B redis-connect-timeout: \fI<msec>\fR -The timeout to use for redis connection set up, in milliseconds. If 0, it -uses the redis\-timeout value. The default is 0. +The timeout to use for Redis connection set up, in milliseconds. +If 0, it uses the \fBredis\-timeout\fR value. +The default is 0. .TP .B redis-expire-records: \fI<yes or no> If Redis record expiration is enabled. If yes, Unbound sets timeout for Redis @@ -2857,6 +2917,52 @@ for multiple unrelated applications. The default database in Redis is 0 while other logical databases need to be explicitly SELECT'ed upon connecting. This option defaults to 0. +.TP +.B redis-replica-server-host: \fI<server address or name>\fR +The IP (either v6 or v4) address or domain name of the Redis replica server. +In general an IP address should be specified as otherwise Unbound will have to +resolve the name of the server every time it establishes a connection +to the server. +This server is treated as a read-only replica server +(https://redis.io/docs/management/replication/#read-only-replica). +If specified, all Redis read commands will go to this replica server, while +the write commands will go to the \fBredis-server-host\fR. +This option defaults to "" (disabled). +.TP +.B redis-replica-server-port: \fI<port number>\fR +The TCP port number of the Redis replica server. +This option defaults to 6379. +.TP +.B redis-replica-server-path: \fI<unix socket path>\fR +The unix socket path to connect to the Redis server. Off by default, and it +can be set to "" to turn this off. Unix sockets may have better throughput +than the IP address option. +.TP +.B redis-replica-server-password: \fI"<password>"\fR +The Redis AUTH password to use for the Redis replica server. +Only relevant if Redis is configured for client password authorisation. +Off by default, and it can be set to "" to turn this off. +.TP +.B redis-replica-timeout: \fI<msec>\fR +The period until when Unbound waits for a response from the Redis replica sever. +If this timeout expires Unbound closes the connection, treats it as +if the Redis replica server does not have the requested data, and will try to +re-establish a new connection later. +This option defaults to 100 milliseconds. +.TP +.B redis-replica-command-timeout: \fI<msec>\fR +The timeout to use for Redis replica commands, in milliseconds. +If 0, it uses the \fBredis\-replica\-timeout\fR value. +The default is 0. +.TP +.B redis-replica-connect-timeout: \fI<msec>\fR +The timeout to use for Redis replica connection set up, in milliseconds. +If 0, it uses the \fBredis\-replica\-timeout\fR value. +The default is 0. +.TP +.B redis-replica-logical-db: \fI<logical database index> +Same as \fBredis-logical-db\fR but for the Redis replica server. +This option defaults to 0. .SS DNSTAP Logging Options DNSTAP support, when compiled in by using \fB\-\-enable\-dnstap\fR, is enabled in the \fBdnstap:\fR section. diff --git a/ipsecmod/ipsecmod.c b/ipsecmod/ipsecmod.c index 76f9b1965e08..1c9e6e6a5a49 100644 --- a/ipsecmod/ipsecmod.c +++ b/ipsecmod/ipsecmod.c @@ -456,7 +456,8 @@ ipsecmod_handle_query(struct module_qstate* qstate, /* Store A/AAAA in cache. */ if(!dns_cache_store(qstate->env, &qstate->qinfo, qstate->return_msg->rep, 0, qstate->prefetch_leeway, - 0, qstate->region, qstate->query_flags, qstate->qstarttime)) { + 0, qstate->region, qstate->query_flags, qstate->qstarttime, + qstate->is_valrec)) { log_err("ipsecmod: out of memory caching record"); } qstate->ext_state[id] = module_finished; diff --git a/iterator/iter_delegpt.c b/iterator/iter_delegpt.c index c8b9a3ffe29d..be5bf482d673 100644 --- a/iterator/iter_delegpt.c +++ b/iterator/iter_delegpt.c @@ -278,7 +278,7 @@ delegpt_count_addr(struct delegpt* dp, size_t* numaddr, size_t* numres, void delegpt_log(enum verbosity_value v, struct delegpt* dp) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; struct delegpt_ns* ns; struct delegpt_addr* a; size_t missing=0, numns=0, numaddr=0, numres=0, numavail=0; diff --git a/iterator/iter_fwd.c b/iterator/iter_fwd.c index b9d42553a8b2..5c104a0a3217 100644 --- a/iterator/iter_fwd.c +++ b/iterator/iter_fwd.c @@ -129,7 +129,7 @@ forwards_insert_data(struct iter_forwards* fwd, uint16_t c, uint8_t* nm, node->namelabs = nmlabs; node->dp = dp; if(!rbtree_insert(fwd->tree, &node->node)) { - char buf[257]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(nm, buf); log_err("duplicate forward zone %s ignored.", buf); delegpt_free_mlc(dp); @@ -331,6 +331,30 @@ make_stub_holes(struct iter_forwards* fwd, struct config_file* cfg) return 1; } +/** make NULL entries for auths */ +static int +make_auth_holes(struct iter_forwards* fwd, struct config_file* cfg) +{ + struct config_auth* a; + uint8_t* dname; + size_t dname_len; + for(a = cfg->auths; a; a = a->next) { + if(!a->name) continue; + dname = sldns_str2wire_dname(a->name, &dname_len); + if(!dname) { + log_err("cannot parse auth name '%s'", a->name); + return 0; + } + if(!fwd_add_stub_hole(fwd, LDNS_RR_CLASS_IN, dname)) { + free(dname); + log_err("out of memory"); + return 0; + } + free(dname); + } + return 1; +} + int forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg) { @@ -353,6 +377,16 @@ forwards_apply_cfg(struct iter_forwards* fwd, struct config_file* cfg) lock_rw_unlock(&fwd->lock); return 0; } + /* TODO: Now we punch holes for auth zones as well so that in + * iterator:forward_request() we see the configured + * delegation point, but code flow/naming is hard to follow. + * Consider having a single tree with configured + * delegation points for all categories + * (stubs, forwards, auths). */ + if(!make_auth_holes(fwd, cfg)) { + lock_rw_unlock(&fwd->lock); + return 0; + } fwd_init_parents(fwd); lock_rw_unlock(&fwd->lock); return 1; @@ -590,3 +624,19 @@ forwards_delete_stub_hole(struct iter_forwards* fwd, uint16_t c, fwd_init_parents(fwd); if(!nolock) { lock_rw_unlock(&fwd->lock); } } + +void +forwards_swap_tree(struct iter_forwards* fwd, struct iter_forwards* data) +{ + rbtree_type* oldtree = fwd->tree; + if(oldtree) { + lock_unprotect(&fwd->lock, oldtree); + } + if(data->tree) { + lock_unprotect(&data->lock, data->tree); + } + fwd->tree = data->tree; + data->tree = oldtree; + lock_protect(&fwd->lock, fwd->tree, sizeof(*fwd->tree)); + lock_protect(&data->lock, data->tree, sizeof(*data->tree)); +} diff --git a/iterator/iter_fwd.h b/iterator/iter_fwd.h index 4527d899c793..095cd96df852 100644 --- a/iterator/iter_fwd.h +++ b/iterator/iter_fwd.h @@ -234,4 +234,13 @@ int forwards_add_stub_hole(struct iter_forwards* fwd, uint16_t c, void forwards_delete_stub_hole(struct iter_forwards* fwd, uint16_t c, uint8_t* nm, int nolock); +/** + * Swap internal tree with preallocated entries. Caller should manage + * the locks. + * @param fwd: the forward data structure. + * @param data: the data structure used to take elements from. This contains + * the old elements on return. + */ +void forwards_swap_tree(struct iter_forwards* fwd, struct iter_forwards* data); + #endif /* ITERATOR_ITER_FWD_H */ diff --git a/iterator/iter_hints.c b/iterator/iter_hints.c index 8b168271c7f0..9faf155ababe 100644 --- a/iterator/iter_hints.c +++ b/iterator/iter_hints.c @@ -181,7 +181,7 @@ hints_insert(struct iter_hints* hints, uint16_t c, struct delegpt* dp, node->noprime = (uint8_t)noprime; if(!name_tree_insert(&hints->tree, &node->node, dp->name, dp->namelen, dp->namelabs, c)) { - char buf[257]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(dp->name, buf); log_err("second hints for zone %s ignored.", buf); delegpt_free_mlc(dp); @@ -611,3 +611,14 @@ hints_delete_stub(struct iter_hints* hints, uint16_t c, uint8_t* nm, name_tree_init_parents(&hints->tree); if(!nolock) { lock_rw_unlock(&hints->lock); } } + +void +hints_swap_tree(struct iter_hints* hints, struct iter_hints* data) +{ + rbnode_type* oldroot = hints->tree.root; + size_t oldcount = hints->tree.count; + hints->tree.root = data->tree.root; + hints->tree.count = data->tree.count; + data->tree.root = oldroot; + data->tree.count = oldcount; +} diff --git a/iterator/iter_hints.h b/iterator/iter_hints.h index 26de323c9e98..87434b5ac2e6 100644 --- a/iterator/iter_hints.h +++ b/iterator/iter_hints.h @@ -198,4 +198,13 @@ int hints_add_stub(struct iter_hints* hints, uint16_t c, struct delegpt* dp, void hints_delete_stub(struct iter_hints* hints, uint16_t c, uint8_t* nm, int nolock); +/** + * Swap internal tree with preallocated entries. Caller should manage + * the locks. + * @param hints: the hints data structure. + * @param data: the data structure used to take elements from. This contains + * the old elements on return. + */ +void hints_swap_tree(struct iter_hints* hints, struct iter_hints* data); + #endif /* ITERATOR_ITER_HINTS_H */ diff --git a/iterator/iter_utils.c b/iterator/iter_utils.c index cacba420e845..1da21896cb20 100644 --- a/iterator/iter_utils.c +++ b/iterator/iter_utils.c @@ -77,41 +77,73 @@ static const char DEFAULT_NAT64_PREFIX[] = "64:ff9b::/96"; /** fillup fetch policy array */ -static void -fetch_fill(struct iter_env* ie, const char* str) +static int +fetch_fill(int* target_fetch_policy, int max_dependency_depth, const char* str) { char* s = (char*)str, *e; int i; - for(i=0; i<ie->max_dependency_depth+1; i++) { - ie->target_fetch_policy[i] = strtol(s, &e, 10); - if(s == e) - fatal_exit("cannot parse fetch policy number %s", s); + for(i=0; i<max_dependency_depth+1; i++) { + target_fetch_policy[i] = strtol(s, &e, 10); + if(s == e) { + log_err("cannot parse fetch policy number %s", s); + return 0; + } s = e; } + return 1; } /** Read config string that represents the target fetch policy */ -static int -read_fetch_policy(struct iter_env* ie, const char* str) +int +read_fetch_policy(int** target_fetch_policy, int* max_dependency_depth, + const char* str) { int count = cfg_count_numbers(str); if(count < 1) { log_err("Cannot parse target fetch policy: \"%s\"", str); return 0; } - ie->max_dependency_depth = count - 1; - ie->target_fetch_policy = (int*)calloc( - (size_t)ie->max_dependency_depth+1, sizeof(int)); - if(!ie->target_fetch_policy) { + *max_dependency_depth = count - 1; + *target_fetch_policy = (int*)calloc( + (size_t)(*max_dependency_depth)+1, sizeof(int)); + if(!*target_fetch_policy) { log_err("alloc fetch policy: out of memory"); return 0; } - fetch_fill(ie, str); + if(!fetch_fill(*target_fetch_policy, *max_dependency_depth, str)) + return 0; return 1; } -/** apply config caps whitelist items to name tree */ -static int +struct rbtree_type* +caps_white_create(void) +{ + struct rbtree_type* caps_white = rbtree_create(name_tree_compare); + if(!caps_white) + log_err("out of memory"); + return caps_white; +} + +/** delete caps_whitelist element */ +static void +caps_free(struct rbnode_type* n, void* ATTR_UNUSED(d)) +{ + if(n) { + free(((struct name_tree_node*)n)->name); + free(n); + } +} + +void +caps_white_delete(struct rbtree_type* caps_white) +{ + if(!caps_white) + return; + traverse_postorder(caps_white, caps_free, NULL); + free(caps_white); +} + +int caps_white_apply_cfg(rbtree_type* ntree, struct config_file* cfg) { struct config_strlist* p; @@ -145,12 +177,41 @@ caps_white_apply_cfg(rbtree_type* ntree, struct config_file* cfg) } int -iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg) +nat64_apply_cfg(struct iter_nat64* nat64, struct config_file* cfg) { const char *nat64_prefix; + + nat64_prefix = cfg->nat64_prefix; + if(!nat64_prefix) + nat64_prefix = cfg->dns64_prefix; + if(!nat64_prefix) + nat64_prefix = DEFAULT_NAT64_PREFIX; + if(!netblockstrtoaddr(nat64_prefix, 0, &nat64->nat64_prefix_addr, + &nat64->nat64_prefix_addrlen, &nat64->nat64_prefix_net)) { + log_err("cannot parse nat64-prefix netblock: %s", nat64_prefix); + return 0; + } + if(!addr_is_ip6(&nat64->nat64_prefix_addr, + nat64->nat64_prefix_addrlen)) { + log_err("nat64-prefix is not IPv6: %s", cfg->nat64_prefix); + return 0; + } + if(!prefixnet_is_nat64(nat64->nat64_prefix_net)) { + log_err("nat64-prefix length it not 32, 40, 48, 56, 64 or 96: %s", + nat64_prefix); + return 0; + } + nat64->use_nat64 = cfg->do_nat64; + return 1; +} + +int +iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg) +{ int i; /* target fetch policy */ - if(!read_fetch_policy(iter_env, cfg->target_fetch_policy)) + if(!read_fetch_policy(&iter_env->target_fetch_policy, + &iter_env->max_dependency_depth, cfg->target_fetch_policy)) return 0; for(i=0; i<iter_env->max_dependency_depth+1; i++) verbose(VERB_QUERY, "target fetch policy for level %d is %d", @@ -170,7 +231,7 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg) } if(cfg->caps_whitelist) { if(!iter_env->caps_white) - iter_env->caps_white = rbtree_create(name_tree_compare); + iter_env->caps_white = caps_white_create(); if(!iter_env->caps_white || !caps_white_apply_cfg( iter_env->caps_white, cfg)) { log_err("Could not set capsforid whitelist"); @@ -179,31 +240,13 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg) } - nat64_prefix = cfg->nat64_prefix; - if(!nat64_prefix) - nat64_prefix = cfg->dns64_prefix; - if(!nat64_prefix) - nat64_prefix = DEFAULT_NAT64_PREFIX; - if(!netblockstrtoaddr(nat64_prefix, 0, &iter_env->nat64_prefix_addr, - &iter_env->nat64_prefix_addrlen, - &iter_env->nat64_prefix_net)) { - log_err("cannot parse nat64-prefix netblock: %s", nat64_prefix); - return 0; - } - if(!addr_is_ip6(&iter_env->nat64_prefix_addr, - iter_env->nat64_prefix_addrlen)) { - log_err("nat64-prefix is not IPv6: %s", cfg->nat64_prefix); - return 0; - } - if(!prefixnet_is_nat64(iter_env->nat64_prefix_net)) { - log_err("nat64-prefix length it not 32, 40, 48, 56, 64 or 96: %s", - nat64_prefix); + if(!nat64_apply_cfg(&iter_env->nat64, cfg)) { + log_err("Could not setup nat64"); return 0; } iter_env->supports_ipv6 = cfg->do_ip6; iter_env->supports_ipv4 = cfg->do_ip4; - iter_env->use_nat64 = cfg->do_nat64; iter_env->outbound_msg_retry = cfg->outbound_msg_retry; iter_env->max_sent_count = cfg->max_sent_count; iter_env->max_query_restarts = cfg->max_query_restarts; @@ -270,7 +313,7 @@ iter_filter_unsuitable(struct iter_env* iter_env, struct module_env* env, if(!iter_env->supports_ipv6 && addr_is_ip6(&a->addr, a->addrlen)) { return -1; /* there is no ip6 available */ } - if(!iter_env->supports_ipv4 && !iter_env->use_nat64 && + if(!iter_env->supports_ipv4 && !iter_env->nat64.use_nat64 && !addr_is_ip6(&a->addr, a->addrlen)) { return -1; /* there is no ip4 available */ } @@ -693,10 +736,11 @@ dns_copy_msg(struct dns_msg* from, struct regional* region) void iter_dns_store(struct module_env* env, struct query_info* msgqinf, struct reply_info* msgrep, int is_referral, time_t leeway, int pside, - struct regional* region, uint16_t flags, time_t qstarttime) + struct regional* region, uint16_t flags, time_t qstarttime, + int is_valrec) { if(!dns_cache_store(env, msgqinf, msgrep, is_referral, leeway, - pside, region, flags, qstarttime)) + pside, region, flags, qstarttime, is_valrec)) log_err("out of memory: cannot store data in cache"); } @@ -1488,14 +1532,15 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf, /* check stub */ if (stub != NULL && stub->dp != NULL) { + enum verbosity_value level = VERB_ALGO; int stub_no_cache = stub->dp->no_cache; lock_rw_unlock(&qstate->env->fwds->lock); - if(stub_no_cache) { - char qname[255+1]; - char dpname[255+1]; + if(verbosity >= level && stub_no_cache) { + char qname[LDNS_MAX_DOMAINLEN]; + char dpname[LDNS_MAX_DOMAINLEN]; dname_str(qinf->qname, qname); dname_str(stub->dp->name, dpname); - verbose(VERB_ALGO, "stub for %s %s has no_cache", qname, dpname); + verbose(level, "stub for %s %s has no_cache", qname, dpname); } if(retdpname) { if(stub->dp->namelen > dpname_storage_len) { @@ -1516,14 +1561,15 @@ iter_stub_fwd_no_cache(struct module_qstate *qstate, struct query_info *qinf, /* Check for forward. */ if (dp) { + enum verbosity_value level = VERB_ALGO; int dp_no_cache = dp->no_cache; lock_rw_unlock(&qstate->env->hints->lock); - if(dp_no_cache) { - char qname[255+1]; - char dpname[255+1]; + if(verbosity >= level && dp_no_cache) { + char qname[LDNS_MAX_DOMAINLEN]; + char dpname[LDNS_MAX_DOMAINLEN]; dname_str(qinf->qname, qname); dname_str(dp->name, dpname); - verbose(VERB_ALGO, "forward for %s %s has no_cache", qname, dpname); + verbose(level, "forward for %s %s has no_cache", qname, dpname); } if(retdpname) { if(dp->namelen > dpname_storage_len) { @@ -1606,3 +1652,12 @@ limit_nsec_ttl(struct dns_msg* msg) } } } + +void +iter_make_minimal(struct reply_info* rep) +{ + size_t rem = rep->ns_numrrsets + rep->ar_numrrsets; + rep->ns_numrrsets = 0; + rep->ar_numrrsets = 0; + rep->rrset_count -= rem; +} diff --git a/iterator/iter_utils.h b/iterator/iter_utils.h index 0361e43775e1..b17b091e6639 100644 --- a/iterator/iter_utils.h +++ b/iterator/iter_utils.h @@ -61,6 +61,7 @@ struct sock_list; struct ub_packed_rrset_key; struct module_stack; struct outside_network; +struct iter_nat64; /* max number of lookups in the cache for target nameserver names. * This stops, for large delegations, N*N lookups in the cache. */ @@ -142,6 +143,7 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional); * @param region: to copy modified (cache is better) rrs back to. * @param flags: with BIT_CD for dns64 AAAA translated queries. * @param qstarttime: time of query start. + * @param is_valrec: if the query is validation recursion and does not get * return void, because we are not interested in alloc errors, * the iterator and validator can operate on the results in their * scratch space (the qstate.region) and are not dependent on the cache. @@ -150,7 +152,8 @@ struct dns_msg* dns_copy_msg(struct dns_msg* from, struct regional* regional); */ void iter_dns_store(struct module_env* env, struct query_info* qinf, struct reply_info* rep, int is_referral, time_t leeway, int pside, - struct regional* region, uint16_t flags, time_t qstarttime); + struct regional* region, uint16_t flags, time_t qstarttime, + int is_valrec); /** * Select randomly with n/m probability. @@ -429,10 +432,54 @@ void iterator_set_ip46_support(struct module_stack* mods, struct module_env* env, struct outside_network* outnet); /** + * Read config string that represents the target fetch policy. + * @param target_fetch_policy: alloced on return. + * @param max_dependency_depth: set on return. + * @param str: the config string + * @return false on failure. + */ +int read_fetch_policy(int** target_fetch_policy, int* max_dependency_depth, + const char* str); + +/** + * Create caps exempt data structure. + * @return NULL on failure. + */ +struct rbtree_type* caps_white_create(void); + +/** + * Delete caps exempt data structure. + * @param caps_white: caps exempt tree. + */ +void caps_white_delete(struct rbtree_type* caps_white); + +/** + * Apply config caps whitelist items to name tree + * @param ntree: caps exempt tree. + * @param cfg: config with options. + */ +int caps_white_apply_cfg(struct rbtree_type* ntree, struct config_file* cfg); + +/** + * Apply config for nat64 + * @param nat64: the nat64 state. + * @param cfg: config with options. + * @return false on failure. + */ +int nat64_apply_cfg(struct iter_nat64* nat64, struct config_file* cfg); + +/** * Limit NSEC and NSEC3 TTL in response, RFC9077 * @param msg: dns message, the SOA record ttl is used to restrict ttls * of NSEC and NSEC3 RRsets. If no SOA record, nothing happens. */ void limit_nsec_ttl(struct dns_msg* msg); +/** + * Make the response minimal. Removed authority and additional section, + * that works when there is an answer in the answer section. + * @param rep: reply to modify. + */ +void iter_make_minimal(struct reply_info* rep); + #endif /* ITERATOR_ITER_UTILS_H */ diff --git a/iterator/iterator.c b/iterator/iterator.c index 59e4b36ce364..e64dfa61ba2d 100644 --- a/iterator/iterator.c +++ b/iterator/iterator.c @@ -71,13 +71,15 @@ #include "sldns/sbuffer.h" /* number of packets */ -int MAX_GLOBAL_QUOTA = 128; +int MAX_GLOBAL_QUOTA = 200; /* in msec */ int UNKNOWN_SERVER_NICENESS = 376; /* in msec */ int USEFUL_SERVER_TOP_TIMEOUT = 120000; /* Equals USEFUL_SERVER_TOP_TIMEOUT*4 */ int BLACKLIST_PENALTY = (120000*4); +/** Timeout when only a single probe query per IP is allowed. */ +int PROBE_MAXRTO = PROBE_MAXRTO_DEFAULT; /* in msec */ static void target_count_increase_nx(struct iter_qstate* iq, int num); @@ -105,16 +107,6 @@ iter_init(struct module_env* env, int id) return 1; } -/** delete caps_whitelist element */ -static void -caps_free(struct rbnode_type* n, void* ATTR_UNUSED(d)) -{ - if(n) { - free(((struct name_tree_node*)n)->name); - free(n); - } -} - void iter_deinit(struct module_env* env, int id) { @@ -126,10 +118,7 @@ iter_deinit(struct module_env* env, int id) free(iter_env->target_fetch_policy); priv_delete(iter_env->priv); donotq_delete(iter_env->donotq); - if(iter_env->caps_white) { - traverse_postorder(iter_env->caps_white, caps_free, NULL); - free(iter_env->caps_white); - } + caps_white_delete(iter_env->caps_white); free(iter_env); env->modinfo[id] = NULL; } @@ -258,7 +247,7 @@ error_supers(struct module_qstate* qstate, int id, struct module_qstate* super) log_err("out of memory adding missing"); } delegpt_mark_neg(dpns, qstate->qinfo.qtype); - if((dpns->got4 == 2 || (!ie->supports_ipv4 && !ie->use_nat64)) && + if((dpns->got4 == 2 || (!ie->supports_ipv4 && !ie->nat64.use_nat64)) && (dpns->got6 == 2 || !ie->supports_ipv6)) { dpns->resolved = 1; /* mark as failed */ target_count_increase_nx(super_iq, 1); @@ -368,7 +357,7 @@ error_response_cache(struct module_qstate* qstate, int id, int rcode) err.security = sec_status_indeterminate; verbose(VERB_ALGO, "store error response in message cache"); iter_dns_store(qstate->env, &qstate->qinfo, &err, 0, 0, 0, NULL, - qstate->query_flags, qstate->qstarttime); + qstate->query_flags, qstate->qstarttime, qstate->is_valrec); return error_response(qstate, id, rcode); } @@ -1092,7 +1081,7 @@ auth_zone_delegpt(struct module_qstate* qstate, struct iter_qstate* iq, /* cache is blacklisted and fallback, and we * already have an auth_zone dp */ if(verbosity>=VERB_ALGO) { - char buf[255+1]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(z->name, buf); verbose(VERB_ALGO, "auth_zone %s " "fallback because cache blacklisted", @@ -1109,7 +1098,7 @@ auth_zone_delegpt(struct module_qstate* qstate, struct iter_qstate* iq, * validation failure, and the zone allows * fallback to the internet, query there. */ if(verbosity>=VERB_ALGO) { - char buf[255+1]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(z->name, buf); verbose(VERB_ALGO, "auth_zone %s " "fallback because cache blacklisted", @@ -1723,7 +1712,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq, */ if(iter_dp_is_useless(&qstate->qinfo, qstate->query_flags, iq->dp, ie->supports_ipv4, ie->supports_ipv6, - ie->use_nat64)) { + ie->nat64.use_nat64)) { int have_dp = 0; if(!can_have_last_resort(qstate->env, iq->dp->name, iq->dp->namelen, iq->qchase.qclass, &have_dp, &iq->dp, qstate->region)) { if(have_dp) { @@ -2033,7 +2022,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq, return 1; if(iq->depth > 0 && iq->target_count && iq->target_count[TARGET_COUNT_QUERIES] > MAX_TARGET_COUNT) { - char s[LDNS_MAX_DOMAINLEN+1]; + char s[LDNS_MAX_DOMAINLEN]; dname_str(qstate->qinfo.qname, s); verbose(VERB_QUERY, "request %s has exceeded the maximum " "number of glue fetches %d", s, @@ -2041,7 +2030,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq, return 2; } if(iq->dp_target_count > MAX_DP_TARGET_COUNT) { - char s[LDNS_MAX_DOMAINLEN+1]; + char s[LDNS_MAX_DOMAINLEN]; dname_str(qstate->qinfo.qname, s); verbose(VERB_QUERY, "request %s has exceeded the maximum " "number of glue fetches %d to a single delegation point", @@ -2087,7 +2076,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq, if(mesh_jostle_exceeded(qstate->env->mesh)) { /* If no ip4 query is possible, that makes * this ns resolved. */ - if(!((ie->supports_ipv4 || ie->use_nat64) && + if(!((ie->supports_ipv4 || ie->nat64.use_nat64) && ((ns->lame && !ns->done_pside4) || (!ns->lame && !ns->got4)))) { ns->resolved = 1; @@ -2096,7 +2085,7 @@ query_for_targets(struct module_qstate* qstate, struct iter_qstate* iq, } } /* Send the A request. */ - if((ie->supports_ipv4 || ie->use_nat64) && + if((ie->supports_ipv4 || ie->nat64.use_nat64) && ((ns->lame && !ns->done_pside4) || (!ns->lame && !ns->got4))) { if(!generate_target_query(qstate, iq, id, @@ -2252,7 +2241,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq, } if(iq->depth > 0 && iq->target_count && iq->target_count[TARGET_COUNT_QUERIES] > MAX_TARGET_COUNT) { - char s[LDNS_MAX_DOMAINLEN+1]; + char s[LDNS_MAX_DOMAINLEN]; dname_str(qstate->qinfo.qname, s); verbose(VERB_QUERY, "request %s has exceeded the maximum " "number of glue fetches %d", s, @@ -2268,14 +2257,14 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq, /* if this nameserver is at a delegation point, but that * delegation point is a stub and we cannot go higher, skip*/ if( ((ie->supports_ipv6 && !ns->done_pside6) || - ((ie->supports_ipv4 || ie->use_nat64) && !ns->done_pside4)) && + ((ie->supports_ipv4 || ie->nat64.use_nat64) && !ns->done_pside4)) && !can_have_last_resort(qstate->env, ns->name, ns->namelen, iq->qchase.qclass, NULL, NULL, NULL)) { log_nametypeclass(VERB_ALGO, "cannot pside lookup ns " "because it is also a stub/forward,", ns->name, LDNS_RR_TYPE_NS, iq->qchase.qclass); if(ie->supports_ipv6) ns->done_pside6 = 1; - if(ie->supports_ipv4 || ie->use_nat64) ns->done_pside4 = 1; + if(ie->supports_ipv4 || ie->nat64.use_nat64) ns->done_pside4 = 1; continue; } /* query for parent-side A and AAAA for nameservers */ @@ -2300,7 +2289,7 @@ processLastResort(struct module_qstate* qstate, struct iter_qstate* iq, return 0; } } - if((ie->supports_ipv4 || ie->use_nat64) && !ns->done_pside4) { + if((ie->supports_ipv4 || ie->nat64.use_nat64) && !ns->done_pside4) { /* Send the A request. */ if(!generate_parentside_target_query(qstate, iq, id, ns->name, ns->namelen, @@ -2569,7 +2558,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, } if(!ie->supports_ipv6) delegpt_no_ipv6(iq->dp); - if(!ie->supports_ipv4 && !ie->use_nat64) + if(!ie->supports_ipv4 && !ie->nat64.use_nat64) delegpt_no_ipv4(iq->dp); delegpt_log(VERB_ALGO, iq->dp); @@ -2741,9 +2730,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, if((iq->chase_flags&BIT_RD) && !(iq->response->rep->flags&BIT_AA)) { verbose(VERB_ALGO, "forwarder, ignoring referral from auth zone"); } else { - lock_rw_wrlock(&qstate->env->auth_zones->lock); - qstate->env->auth_zones->num_query_up++; - lock_rw_unlock(&qstate->env->auth_zones->lock); + qstate->env->mesh->num_query_authzone_up++; iq->num_current_queries++; iq->chase_to_rd = 0; iq->dnssec_lame_query = 0; @@ -3046,7 +3033,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, target_count_increase_global_quota(iq, 1); if(iq->target_count && iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] > MAX_GLOBAL_QUOTA) { - char s[LDNS_MAX_DOMAINLEN+1]; + char s[LDNS_MAX_DOMAINLEN]; dname_str(qstate->qinfo.qname, s); verbose(VERB_QUERY, "request %s has exceeded the maximum " "global quota on number of upstream queries %d", s, @@ -3070,9 +3057,9 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq, real_addr = target->addr; real_addrlen = target->addrlen; - if(ie->use_nat64 && target->addr.ss_family == AF_INET) { - addr_to_nat64(&target->addr, &ie->nat64_prefix_addr, - ie->nat64_prefix_addrlen, ie->nat64_prefix_net, + if(ie->nat64.use_nat64 && target->addr.ss_family == AF_INET) { + addr_to_nat64(&target->addr, &ie->nat64.nat64_prefix_addr, + ie->nat64.nat64_prefix_addrlen, ie->nat64.nat64_prefix_net, &real_addr, &real_addrlen); log_name_addr(VERB_QUERY, "applied NAT64:", iq->dp->name, &real_addr, real_addrlen); @@ -3296,6 +3283,16 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, iq->num_target_queries = 0; return processDSNSFind(qstate, iq, id); } + if(iq->qchase.qtype == LDNS_RR_TYPE_DNSKEY && SERVE_EXPIRED + && qstate->is_valrec && + reply_find_answer_rrset(&iq->qchase, iq->response->rep) != NULL) { + /* clean out the authority section, if any, so it + * does not overwrite dnssec valid data in the + * validation recursion lookup. */ + verbose(VERB_ALGO, "make DNSKEY minimal for serve " + "expired"); + iter_make_minimal(iq->response->rep); + } if(!qstate->no_cache_store) iter_dns_store(qstate->env, &iq->response->qinfo, iq->response->rep, @@ -3303,7 +3300,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, qstate->prefetch_leeway, iq->dp&&iq->dp->has_parent_side_NS, qstate->region, qstate->query_flags, - qstate->qstarttime); + qstate->qstarttime, qstate->is_valrec); /* close down outstanding requests to be discarded */ outbound_list_clear(&iq->outlist); iq->num_current_queries = 0; @@ -3397,7 +3394,7 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, /* no prefetch-leeway, since its not the answer */ iter_dns_store(qstate->env, &iq->response->qinfo, iq->response->rep, 1, 0, 0, NULL, 0, - qstate->qstarttime); + qstate->qstarttime, qstate->is_valrec); if(iq->store_parent_NS) iter_store_parentside_NS(qstate->env, iq->response->rep); @@ -3527,7 +3524,8 @@ processQueryResponse(struct module_qstate* qstate, struct iter_qstate* iq, iter_dns_store(qstate->env, &iq->response->qinfo, iq->response->rep, 1, qstate->prefetch_leeway, iq->dp&&iq->dp->has_parent_side_NS, NULL, - qstate->query_flags, qstate->qstarttime); + qstate->query_flags, qstate->qstarttime, + qstate->is_valrec); /* set the current request's qname to the new value. */ iq->qchase.qname = sname; iq->qchase.qname_len = snamelen; @@ -3871,7 +3869,7 @@ processTargetResponse(struct module_qstate* qstate, int id, } else { verbose(VERB_ALGO, "iterator TargetResponse failed"); delegpt_mark_neg(dpns, qstate->qinfo.qtype); - if((dpns->got4 == 2 || (!ie->supports_ipv4 && !ie->use_nat64)) && + if((dpns->got4 == 2 || (!ie->supports_ipv4 && !ie->nat64.use_nat64)) && (dpns->got6 == 2 || !ie->supports_ipv6)) { dpns->resolved = 1; /* fail the target */ /* do not count cached answers */ @@ -4154,7 +4152,7 @@ processFinished(struct module_qstate* qstate, struct iter_qstate* iq, iq->response->rep, 0, qstate->prefetch_leeway, iq->dp&&iq->dp->has_parent_side_NS, qstate->region, qstate->query_flags, - qstate->qstarttime); + qstate->qstarttime, qstate->is_valrec); } } qstate->return_rcode = LDNS_RCODE_NOERROR; @@ -4334,6 +4332,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq, } /* Copy the edns options we may got from the back end */ + qstate->edns_opts_back_in = NULL; if(edns.opt_list_in) { qstate->edns_opts_back_in = edns_opt_copy_region(edns.opt_list_in, qstate->region); diff --git a/iterator/iterator.h b/iterator/iterator.h index 46701f6eee75..ae4b4e45170a 100644 --- a/iterator/iterator.h +++ b/iterator/iterator.h @@ -46,8 +46,6 @@ #include "util/data/msgreply.h" #include "util/module.h" struct delegpt; -struct iter_hints; -struct iter_forwards; struct iter_donotq; struct iter_prep_list; struct iter_priv; @@ -108,15 +106,9 @@ extern int BLACKLIST_PENALTY; #define EMPTY_NODATA_RETRY_COUNT 2 /** - * Global state for the iterator. + * Iterator global state for nat64. */ -struct iter_env { - /** A flag to indicate whether or not we have an IPv6 route */ - int supports_ipv6; - - /** A flag to indicate whether or not we have an IPv4 route */ - int supports_ipv4; - +struct iter_nat64 { /** A flag to locally apply NAT64 to make IPv4 addrs into IPv6 */ int use_nat64; @@ -128,6 +120,20 @@ struct iter_env { /** CIDR mask length of NAT64 prefix */ int nat64_prefix_net; +}; + +/** + * Global state for the iterator. + */ +struct iter_env { + /** A flag to indicate whether or not we have an IPv6 route */ + int supports_ipv6; + + /** A flag to indicate whether or not we have an IPv4 route */ + int supports_ipv4; + + /** State for nat64 */ + struct iter_nat64 nat64; /** A set of inetaddrs that should never be queried. */ struct iter_donotq* donotq; diff --git a/libunbound/libworker.c b/libunbound/libworker.c index da7d4c22440d..f0496452b521 100644 --- a/libunbound/libworker.c +++ b/libunbound/libworker.c @@ -423,7 +423,7 @@ int libworker_bg(struct ub_ctx* ctx) static int fill_canon(struct ub_result* res, uint8_t* s) { - char buf[255+2]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(s, buf); res->canonname = strdup(buf); return res->canonname != 0; @@ -1059,6 +1059,20 @@ void dtio_mainfdcallback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), } #endif +void fast_reload_service_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), + void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} + +int fast_reload_client_callback(struct comm_point* ATTR_UNUSED(c), + void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), + struct comm_reply* ATTR_UNUSED(repinfo)) +{ + log_assert(0); + return 0; +} + #ifdef HAVE_NGTCP2 void doq_client_event_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), void* ATTR_UNUSED(arg)) diff --git a/libunbound/unbound.h b/libunbound/unbound.h index ef2c5c0679f6..bdcf4edeca5f 100644 --- a/libunbound/unbound.h +++ b/libunbound/unbound.h @@ -849,6 +849,12 @@ struct ub_server_stats { long long mem_quic; /** number of queries over (DNS over) QUIC */ long long qquic; + /** number of queries removed due to discard-timeout */ + long long num_queries_discard_timeout; + /** number of queries removed due to wait-limit */ + long long num_queries_wait_limit; + /** number of dns error reports generated */ + long long num_dns_error_reports; }; /** diff --git a/pythonmod/interface.i b/pythonmod/interface.i index 810b1449d34e..2040fb9e8adf 100644 --- a/pythonmod/interface.i +++ b/pythonmod/interface.i @@ -204,7 +204,7 @@ struct query_info { %inline %{ PyObject* dnameAsStr(PyObject* dname) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; buf[0] = '\0'; dname_str((uint8_t*)PyBytes_AsString(dname), buf); return PyString_FromString(buf); diff --git a/pythonmod/pythonmod_utils.c b/pythonmod/pythonmod_utils.c index aebe4d2bbb24..fc9921aa1d1e 100644 --- a/pythonmod/pythonmod_utils.c +++ b/pythonmod/pythonmod_utils.c @@ -73,7 +73,7 @@ int storeQueryInCache(struct module_qstate* qstate, struct query_info* qinfo, return dns_cache_store(qstate->env, qinfo, msgrep, is_referral, qstate->prefetch_leeway, 0, NULL, qstate->query_flags, - qstate->qstarttime); + qstate->qstarttime, qstate->is_valrec); } /* Invalidate the message associated with query_info stored in message cache */ diff --git a/respip/respip.c b/respip/respip.c index db48f176e460..353a0fd783e5 100644 --- a/respip/respip.c +++ b/respip/respip.c @@ -105,6 +105,7 @@ respip_sockaddr_find_or_create(struct respip_set* set, struct sockaddr_storage* socklen_t addrlen, int net, int create, const char* ipstr) { struct resp_addr* node; + log_assert(set); node = (struct resp_addr*)addr_tree_find(&set->ip_tree, addr, addrlen, net); if(!node && create) { node = regional_alloc_zero(set->region, sizeof(*node)); @@ -128,6 +129,7 @@ void respip_sockaddr_delete(struct respip_set* set, struct resp_addr* node) { struct resp_addr* prev; + log_assert(set); prev = (struct resp_addr*)rbtree_previous((struct rbnode_type*)node); lock_rw_destroy(&node->lock); (void)rbtree_delete(&set->ip_tree, node); @@ -146,6 +148,7 @@ respip_find_or_create(struct respip_set* set, const char* ipstr, int create) struct sockaddr_storage addr; int net; socklen_t addrlen; + log_assert(set); if(!netblockstrtoaddr(ipstr, 0, &addr, &addrlen, &net)) { log_err("cannot parse netblock: '%s'", ipstr); @@ -160,6 +163,7 @@ respip_tag_cfg(struct respip_set* set, const char* ipstr, const uint8_t* taglist, size_t taglen) { struct resp_addr* node; + log_assert(set); if(!(node=respip_find_or_create(set, ipstr, 1))) return 0; @@ -183,6 +187,7 @@ respip_action_cfg(struct respip_set* set, const char* ipstr, { struct resp_addr* node; enum respip_action action; + log_assert(set); if(!(node=respip_find_or_create(set, ipstr, 1))) return 0; @@ -325,6 +330,7 @@ static int respip_data_cfg(struct respip_set* set, const char* ipstr, const char* rrstr) { struct resp_addr* node; + log_assert(set); node=respip_find_or_create(set, ipstr, 0); if(!node || node->action == respip_none) { @@ -344,6 +350,7 @@ respip_set_apply_cfg(struct respip_set* set, char* const* tagname, int num_tags, struct config_strbytelist* p; struct config_str2list* pa; struct config_str2list* pd; + log_assert(set); set->tagname = tagname; set->num_tags = num_tags; @@ -609,6 +616,7 @@ respip_addr_lookup(const struct reply_info *rep, struct respip_set* rs, struct resp_addr* ra; struct sockaddr_storage ss; socklen_t addrlen; + log_assert(rs); lock_rw_rdlock(&rs->lock); for(i=0; i<rep->an_numrrsets; i++) { @@ -867,7 +875,8 @@ respip_rewrite_reply(const struct query_info* qinfo, const struct respip_client_info* cinfo, const struct reply_info* rep, struct reply_info** new_repp, struct respip_action_info* actinfo, struct ub_packed_rrset_key** alias_rrset, int search_only, - struct regional* region, struct auth_zones* az, int* rpz_passthru) + struct regional* region, struct auth_zones* az, int* rpz_passthru, + struct views* views, struct respip_set* ipset) { const uint8_t* ctaglist; size_t ctaglen; @@ -876,7 +885,6 @@ respip_rewrite_reply(const struct query_info* qinfo, struct config_strlist** tag_datas; size_t tag_datas_size; struct view* view = NULL; - struct respip_set* ipset = NULL; size_t rrset_id = 0, rr_id = 0; enum respip_action action = respip_none; int tag = -1; @@ -899,8 +907,20 @@ respip_rewrite_reply(const struct query_info* qinfo, tag_actions_size = cinfo->tag_actions_size; tag_datas = cinfo->tag_datas; tag_datas_size = cinfo->tag_datas_size; - view = cinfo->view; - ipset = cinfo->respip_set; + if(cinfo->view) { + view = cinfo->view; + lock_rw_rdlock(&view->lock); + } else if(cinfo->view_name) { + view = views_find_view(views, cinfo->view_name, 0); + if(!view) { + /* If the view no longer exists, the rewrite can not + * be processed further. */ + verbose(VERB_ALGO, "respip: failed because view %s no " + "longer exists", cinfo->view_name); + return 0; + } + /* The view is rdlocked by views_find_view. */ + } log_assert(ipset); @@ -915,7 +935,6 @@ respip_rewrite_reply(const struct query_info* qinfo, * Note also that we assume 'view' is valid in this function, which * should be safe (see unbound bug #1191) */ if(view) { - lock_rw_rdlock(&view->lock); if(view->respip_set) { if((raddr = respip_addr_lookup(rep, view->respip_set, &rrset_id, &rr_id))) { @@ -961,7 +980,7 @@ respip_rewrite_reply(const struct query_info* qinfo, struct sockaddr_storage ss; socklen_t ss_len = 0; char nm[256], ip[256]; - char qn[255+1]; + char qn[LDNS_MAX_DOMAINLEN]; if(!rdata2sockaddr(rep->rrsets[rrset_id]->entry.data, ntohs(rep->rrsets[rrset_id]->rk.type), rr_id, &ss, &ss_len)) snprintf(ip, sizeof(ip), "invalidRRdata"); else @@ -1101,7 +1120,8 @@ respip_operate(struct module_qstate* qstate, enum module_ev event, int id, qstate->client_info, qstate->return_msg->rep, &new_rep, &actinfo, &alias_rrset, 0, qstate->region, qstate->env->auth_zones, - &qstate->rpz_passthru)) { + &qstate->rpz_passthru, qstate->env->views, + qstate->env->respip_set)) { goto servfail; } if(actinfo.action != respip_none) { @@ -1149,7 +1169,8 @@ respip_merge_cname(struct reply_info* base_rep, const struct query_info* qinfo, const struct reply_info* tgt_rep, const struct respip_client_info* cinfo, int must_validate, struct reply_info** new_repp, struct regional* region, - struct auth_zones* az) + struct auth_zones* az, struct views* views, + struct respip_set* respip_set) { struct reply_info* new_rep; struct reply_info* tmp_rep = NULL; /* just a placeholder */ @@ -1176,7 +1197,7 @@ respip_merge_cname(struct reply_info* base_rep, /* see if the target reply would be subject to a response-ip action. */ if(!respip_rewrite_reply(qinfo, cinfo, tgt_rep, &tmp_rep, &actinfo, - &alias_rrset, 1, region, az, NULL)) + &alias_rrset, 1, region, az, NULL, views, respip_set)) return 0; if(actinfo.action != respip_none) { log_info("CNAME target of redirect response-ip action would " @@ -1229,7 +1250,8 @@ respip_inform_super(struct module_qstate* qstate, int id, if(!respip_merge_cname(super->return_msg->rep, &qstate->qinfo, qstate->return_msg->rep, super->client_info, super->env->need_to_validate, &new_rep, super->region, - qstate->env->auth_zones)) + qstate->env->auth_zones, qstate->env->views, + qstate->env->respip_set)) goto fail; super->return_msg->rep = new_rep; return; @@ -1326,3 +1348,35 @@ respip_inform_print(struct respip_action_info* respip_actinfo, uint8_t* qname, (actionstr) ? actionstr : "inform", srcip, port); log_nametypeclass(NO_VERBOSE, txt, qname, qtype, qclass); } + +size_t respip_set_get_mem(struct respip_set* set) +{ + size_t m; + if(!set) return 0; + m = sizeof(*set); + lock_rw_rdlock(&set->lock); + m += regional_get_mem(set->region); + lock_rw_unlock(&set->lock); + return m; +} + +void +respip_set_swap_tree(struct respip_set* respip_set, + struct respip_set* data) +{ + rbnode_type* oldroot = respip_set->ip_tree.root; + size_t oldcount = respip_set->ip_tree.count; + struct regional* oldregion = respip_set->region; + char* const* oldtagname = respip_set->tagname; + int oldnum_tags = respip_set->num_tags; + respip_set->ip_tree.root = data->ip_tree.root; + respip_set->ip_tree.count = data->ip_tree.count; + respip_set->region = data->region; + respip_set->tagname = data->tagname; + respip_set->num_tags = data->num_tags; + data->ip_tree.root = oldroot; + data->ip_tree.count = oldcount; + data->region = oldregion; + data->tagname = oldtagname; + data->num_tags = oldnum_tags; +} diff --git a/respip/respip.h b/respip/respip.h index e4ab5cc9cce3..6469854c53cb 100644 --- a/respip/respip.h +++ b/respip/respip.h @@ -23,7 +23,8 @@ struct respip_set { struct regional* region; struct rbtree_type ip_tree; - lock_rw_type lock; /* lock on the respip tree */ + lock_rw_type lock; /* lock on the respip tree. It is ordered + after views and before hints, stubs and local zones. */ char* const* tagname; /* shallow copy of tag names, for logging */ int num_tags; /* number of tagname entries */ }; @@ -59,7 +60,6 @@ struct respip_addr_info; * This is essentially a subset of acl_addr (except for respip_set) but * defined as a separate structure to avoid dependency on the daemon-specific * structure. - * respip_set is supposed to refer to the response-ip set for the global view. */ struct respip_client_info { uint8_t* taglist; @@ -68,8 +68,12 @@ struct respip_client_info { size_t tag_actions_size; struct config_strlist** tag_datas; size_t tag_datas_size; + /** The view for the action, during cache callback that is by + * pointer. */ struct view* view; - struct respip_set* respip_set; + /** If from module query state, the view pointer is NULL, but the + * name is stored in reference to the view. */ + char* view_name; }; /** @@ -149,13 +153,16 @@ int respip_views_apply_cfg(struct views* vs, struct config_file* cfg, * on error. * @param region: allocator to build *new_repp. * @param az: auth zones containing RPZ information. + * @param views: views tree to lookup view used. + * @param respip_set: the respip set for the global view. * @return 1 on success, 0 on error. */ int respip_merge_cname(struct reply_info* base_rep, const struct query_info* qinfo, const struct reply_info* tgt_rep, const struct respip_client_info* cinfo, int must_validate, struct reply_info** new_repp, struct regional* region, - struct auth_zones* az); + struct auth_zones* az, struct views* views, + struct respip_set* respip_set); /** * See if any IP-based action should apply to any IP address of AAAA/A answer @@ -178,6 +185,8 @@ int respip_merge_cname(struct reply_info* base_rep, * @param region: allocator to build *new_repp. * @param rpz_passthru: keeps track of query state can have passthru that * stops further rpz processing. Or NULL for cached answer processing. + * @param views: views tree to lookup view used. + * @param ipset: the respip set for the global view. * @return 1 on success, 0 on error. */ int respip_rewrite_reply(const struct query_info* qinfo, @@ -186,7 +195,7 @@ int respip_rewrite_reply(const struct query_info* qinfo, struct respip_action_info* actinfo, struct ub_packed_rrset_key** alias_rrset, int search_only, struct regional* region, struct auth_zones* az, - int* rpz_passthru); + int* rpz_passthru, struct views* views, struct respip_set* ipset); /** * Get the response-ip function block. @@ -302,4 +311,18 @@ respip_sockaddr_delete(struct respip_set* set, struct resp_addr* node); struct ub_packed_rrset_key* respip_copy_rrset(const struct ub_packed_rrset_key* key, struct regional* region); + +/** Get memory usage of respip set tree. The routine locks and unlocks the + * set for reading. */ +size_t respip_set_get_mem(struct respip_set* set); + +/** + * Swap internal tree with preallocated entries. Caller should manage + * the locks. + * @param respip_set: response ip tree + * @param data: preallocated information. + */ +void respip_set_swap_tree(struct respip_set* respip_set, + struct respip_set* data); + #endif /* RESPIP_RESPIP_H */ diff --git a/services/authzone.c b/services/authzone.c index 6f6c55d4397d..3c3dc9ad05d9 100644 --- a/services/authzone.c +++ b/services/authzone.c @@ -1578,7 +1578,7 @@ auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg) cfg->chrootdir, strlen(cfg->chrootdir)) == 0) zfilename += strlen(cfg->chrootdir); if(verbosity >= VERB_ALGO) { - char nm[255+1]; + char nm[LDNS_MAX_DOMAINLEN]; dname_str(z->name, nm); verbose(VERB_ALGO, "read zonefile %s for %s", zfilename, nm); } @@ -1942,7 +1942,7 @@ static int auth_zone_zonemd_check_hash(struct auth_zone* z, unsupported_reason = *reason; /* continue to check for valid ZONEMD */ if(verbosity >= VERB_ALGO) { - char zstr[255+1]; + char zstr[LDNS_MAX_DOMAINLEN]; dname_str(z->name, zstr); verbose(VERB_ALGO, "auth-zone %s ZONEMD %d %d is unsupported: %s", zstr, (int)scheme, (int)hashalgo, *reason); } @@ -1950,7 +1950,7 @@ static int auth_zone_zonemd_check_hash(struct auth_zone* z, continue; } if(verbosity >= VERB_ALGO) { - char zstr[255+1]; + char zstr[LDNS_MAX_DOMAINLEN]; dname_str(z->name, zstr); if(!*reason) verbose(VERB_ALGO, "auth-zone %s ZONEMD hash is correct", zstr); @@ -1973,7 +1973,7 @@ static int auth_zone_zonemd_check_hash(struct auth_zone* z, if(!*reason) *reason = "no ZONEMD records found"; if(verbosity >= VERB_ALGO) { - char zstr[255+1]; + char zstr[LDNS_MAX_DOMAINLEN]; dname_str(z->name, zstr); verbose(VERB_ALGO, "auth-zone %s ZONEMD failed: %s", zstr, *reason); } @@ -2317,9 +2317,6 @@ auth_free_masters(struct auth_master* list) } } -/** delete auth xfer structure - * @param xfr: delete this xfer and its tasks. - */ void auth_xfer_delete(struct auth_xfer* xfr) { @@ -3610,9 +3607,7 @@ int auth_zones_answer(struct auth_zones* az, struct module_env* env, return 0; } lock_rw_unlock(&z->lock); - lock_rw_wrlock(&az->lock); - az->num_query_down++; - lock_rw_unlock(&az->lock); + env->mesh->num_query_authzone_down++; auth_error_encode(qinfo, env, edns, repinfo, buf, temp, LDNS_RCODE_SERVFAIL); return 1; @@ -3625,9 +3620,7 @@ int auth_zones_answer(struct auth_zones* az, struct module_env* env, /* fallback to regular answering (recursive) */ return 0; } - lock_rw_wrlock(&az->lock); - az->num_query_down++; - lock_rw_unlock(&az->lock); + env->mesh->num_query_authzone_down++; /* encode answer */ if(!r) @@ -4803,8 +4796,8 @@ log_rrlist_position(const char* label, struct auth_chunk* rr_chunk, { sldns_buffer pkt; size_t dlen; - uint8_t buf[256]; - char str[256]; + uint8_t buf[LDNS_MAX_DOMAINLEN]; + char str[LDNS_MAX_DOMAINLEN]; char typestr[32]; sldns_buffer_init_frm_data(&pkt, rr_chunk->data, rr_chunk->len); sldns_buffer_set_position(&pkt, (size_t)(rr_dname - @@ -5231,7 +5224,7 @@ xfr_write_after_update(struct auth_xfer* xfr, struct module_env* env) cfg->chrootdir, strlen(cfg->chrootdir)) == 0) zfilename += strlen(cfg->chrootdir); if(verbosity >= VERB_ALGO) { - char nm[255+1]; + char nm[LDNS_MAX_DOMAINLEN]; dname_str(z->name, nm); verbose(VERB_ALGO, "write zonefile %s for %s", zfilename, nm); } @@ -5348,7 +5341,7 @@ xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env, /* holding z lock */ auth_zone_verify_zonemd(z, env, &env->mesh->mods, NULL, 0, 0); if(z->zone_expired) { - char zname[256]; + char zname[LDNS_MAX_DOMAINLEN]; /* ZONEMD must have failed */ /* reacquire locks, so we hold xfr lock on exit of routine, * and both xfr and z again after releasing xfr for potential @@ -5380,7 +5373,7 @@ xfr_process_chunk_list(struct auth_xfer* xfr, struct module_env* env, lock_rw_unlock(&z->lock); if(verbosity >= VERB_QUERY && xfr->have_zone) { - char zname[256]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_QUERY, "auth zone %s updated to serial %u", zname, (unsigned)xfr->serial); @@ -5442,7 +5435,7 @@ xfr_transfer_lookup_host(struct auth_xfer* xfr, struct module_env* env) qinfo.local_alias = NULL; if(verbosity >= VERB_ALGO) { char buf1[512]; - char buf2[LDNS_MAX_DOMAINLEN+1]; + char buf2[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, buf2); snprintf(buf1, sizeof(buf1), "auth zone %s: master lookup" " for task_transfer", buf2); @@ -5498,7 +5491,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env) /* the ones that are not in addr format are supposed * to be looked up. The lookup has failed however, * so skip them */ - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); log_err("%s: failed lookup, cannot transfer from master %s", zname, master->host); @@ -5537,7 +5530,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env) &addr, addrlen, -1, master->ssl, master->host, master->file, env->cfg); if(!xfr->task_transfer->cp) { - char zname[255+1], as[256]; + char zname[LDNS_MAX_DOMAINLEN], as[256]; dname_str(xfr->name, zname); addr_port_to_str(&addr, addrlen, as, sizeof(as)); verbose(VERB_ALGO, "cannot create http cp " @@ -5546,7 +5539,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env) } comm_timer_set(xfr->task_transfer->timer, &t); if(verbosity >= VERB_ALGO) { - char zname[255+1], as[256]; + char zname[LDNS_MAX_DOMAINLEN], as[256]; dname_str(xfr->name, zname); addr_port_to_str(&addr, addrlen, as, sizeof(as)); verbose(VERB_ALGO, "auth zone %s transfer next HTTP fetch from %s started", zname, as); @@ -5569,7 +5562,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env) env->scratch_buffer, -1, auth_name != NULL, auth_name); if(!xfr->task_transfer->cp) { - char zname[255+1], as[256]; + char zname[LDNS_MAX_DOMAINLEN], as[256]; dname_str(xfr->name, zname); addr_port_to_str(&addr, addrlen, as, sizeof(as)); verbose(VERB_ALGO, "cannot create tcp cp connection for " @@ -5578,7 +5571,7 @@ xfr_transfer_init_fetch(struct auth_xfer* xfr, struct module_env* env) } comm_timer_set(xfr->task_transfer->timer, &t); if(verbosity >= VERB_ALGO) { - char zname[255+1], as[256]; + char zname[LDNS_MAX_DOMAINLEN], as[256]; dname_str(xfr->name, zname); addr_port_to_str(&addr, addrlen, as, sizeof(as)); verbose(VERB_ALGO, "auth zone %s transfer next %s fetch from %s started", zname, @@ -5602,7 +5595,7 @@ xfr_transfer_nexttarget_or_end(struct auth_xfer* xfr, struct module_env* env) * and that calls the callback just like a full * lookup and lookup failures also call callback */ if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s transfer next target lookup", zname); } @@ -5625,7 +5618,7 @@ xfr_transfer_nexttarget_or_end(struct auth_xfer* xfr, struct module_env* env) xfr_transfer_nextmaster(xfr); } if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s transfer failed, wait", zname); } @@ -5728,14 +5721,14 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf, lookup_target, answer, wanted_qtype); } else { if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup has nodata", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A")); } } } else { if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup has no answer", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A")); } @@ -5743,7 +5736,7 @@ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf, regional_free_all(temp); } else { if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup failed", zname, xfr->task_transfer->lookup_target->host, (xfr->task_transfer->lookup_aaaa?"AAAA":"A")); } @@ -6385,7 +6378,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env, /* the ones that are not in addr format are supposed * to be looked up. The lookup has failed however, * so skip them */ - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); log_err("%s: failed lookup, cannot probe to master %s", zname, master->host); @@ -6427,7 +6420,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env, xfr->task_probe->cp = outnet_comm_point_for_udp(env->outnet, auth_xfer_probe_udp_callback, xfr, &addr, addrlen); if(!xfr->task_probe->cp) { - char zname[255+1], as[256]; + char zname[LDNS_MAX_DOMAINLEN], as[256]; dname_str(xfr->name, zname); addr_port_to_str(&addr, addrlen, as, sizeof(as)); verbose(VERB_ALGO, "cannot create udp cp for " @@ -6447,7 +6440,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env, /* send udp packet */ if(!comm_point_send_udp_msg(xfr->task_probe->cp, env->scratch_buffer, (struct sockaddr*)&addr, addrlen, 0)) { - char zname[255+1], as[256]; + char zname[LDNS_MAX_DOMAINLEN], as[256]; dname_str(xfr->name, zname); addr_port_to_str(&addr, addrlen, as, sizeof(as)); verbose(VERB_ALGO, "failed to send soa probe for %s to %s", @@ -6455,7 +6448,7 @@ xfr_probe_send_probe(struct auth_xfer* xfr, struct module_env* env, return 0; } if(verbosity >= VERB_ALGO) { - char zname[255+1], as[256]; + char zname[LDNS_MAX_DOMAINLEN], as[256]; dname_str(xfr->name, zname); addr_port_to_str(&addr, addrlen, as, sizeof(as)); verbose(VERB_ALGO, "auth zone %s soa probe sent to %s", zname, @@ -6486,7 +6479,7 @@ auth_xfer_probe_timer_callback(void* arg) } if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s soa probe timeout", zname); } @@ -6534,7 +6527,7 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err, &serial)) { /* successful lookup */ if(verbosity >= VERB_ALGO) { - char buf[256]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, buf); verbose(VERB_ALGO, "auth zone %s: soa probe " "serial is %u", buf, (unsigned)serial); @@ -6573,14 +6566,14 @@ auth_xfer_probe_udp_callback(struct comm_point* c, void* arg, int err, } } else { if(verbosity >= VERB_ALGO) { - char buf[256]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, buf); verbose(VERB_ALGO, "auth zone %s: bad reply to soa probe", buf); } } } else { if(verbosity >= VERB_ALGO) { - char buf[256]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, buf); verbose(VERB_ALGO, "auth zone %s: soa probe failed", buf); } @@ -6637,7 +6630,7 @@ xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env) qinfo.local_alias = NULL; if(verbosity >= VERB_ALGO) { char buf1[512]; - char buf2[LDNS_MAX_DOMAINLEN+1]; + char buf2[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, buf2); snprintf(buf1, sizeof(buf1), "auth zone %s: master lookup" " for task_probe", buf2); @@ -6683,7 +6676,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env) * and that calls the callback just like a full * lookup and lookup failures also call callback */ if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s probe next target lookup", zname); } @@ -6696,7 +6689,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env) * allow_notify addrs */ probe_copy_masters_for_allow_notify(xfr); if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s probe: notify addrs updated", zname); } @@ -6704,7 +6697,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env) /* only wanted lookups for copy, stop probe and start wait */ xfr->task_probe->only_lookup = 0; if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s probe: finished only_lookup", zname); } @@ -6730,7 +6723,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env) if(xfr->task_probe->have_new_lease) { /* if zone not updated, start the wait timer again */ if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth_zone %s unchanged, new lease, wait", zname); } @@ -6741,7 +6734,7 @@ xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env) xfr_set_timeout(xfr, env, 0, 0); } else { if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s soa probe failed, wait to retry", zname); } @@ -6791,14 +6784,14 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf, lookup_target, answer, wanted_qtype); } else { if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup has nodata", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A")); } } } else { if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup has no address", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A")); } @@ -6806,7 +6799,7 @@ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf, regional_free_all(temp); } else { if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup failed", zname, xfr->task_probe->lookup_target->host, (xfr->task_probe->lookup_aaaa?"AAAA":"A")); } @@ -6980,7 +6973,7 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env, if(!xfr->task_nextprobe->timer) { /* failed to malloc memory. likely zone transfer * also fails for that. skip the timeout */ - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); log_err("cannot allocate timer, no refresh for %s", zname); @@ -7001,7 +6994,7 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env, xfr->task_probe->only_lookup = 1; } if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(xfr->name, zname); verbose(VERB_ALGO, "auth zone %s timeout in %d seconds", zname, (int)tv.tv_sec); @@ -7010,6 +7003,18 @@ xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env, comm_timer_set(xfr->task_nextprobe->timer, &tv); } +void auth_xfer_pickup_initial_zone(struct auth_xfer* x, struct module_env* env) +{ + /* set lease_time, because we now have timestamp in env, + * (not earlier during startup and apply_cfg), and this + * notes the start time when the data was acquired */ + if(x->have_zone) + x->lease_time = *env->now; + if(x->task_nextprobe && x->task_nextprobe->worker == NULL) { + xfr_set_timeout(x, env, 0, 1); + } +} + /** initial pick up of worker timeouts, ties events to worker event loop */ void auth_xfer_pickup_initial(struct auth_zones* az, struct module_env* env) @@ -7018,14 +7023,7 @@ auth_xfer_pickup_initial(struct auth_zones* az, struct module_env* env) lock_rw_wrlock(&az->lock); RBTREE_FOR(x, struct auth_xfer*, &az->xtree) { lock_basic_lock(&x->lock); - /* set lease_time, because we now have timestamp in env, - * (not earlier during startup and apply_cfg), and this - * notes the start time when the data was acquired */ - if(x->have_zone) - x->lease_time = *env->now; - if(x->task_nextprobe && x->task_nextprobe->worker == NULL) { - xfr_set_timeout(x, env, 0, 1); - } + auth_xfer_pickup_initial_zone(x, env); lock_basic_unlock(&x->lock); } lock_rw_unlock(&az->lock); @@ -7788,7 +7786,7 @@ static void auth_zone_log(uint8_t* name, enum verbosity_value level, va_list args; va_start(args, format); if(verbosity >= level) { - char str[255+1]; + char str[LDNS_MAX_DOMAINLEN]; char msg[MAXSYSLOGMSGLEN]; dname_str(name, str); vsnprintf(msg, sizeof(msg), format, args); @@ -7990,7 +7988,7 @@ static int zonemd_check_dnssec_soazonemd(struct auth_zone* z, static void auth_zone_zonemd_fail(struct auth_zone* z, struct module_env* env, char* reason, char* why_bogus, char** result) { - char zstr[255+1]; + char zstr[LDNS_MAX_DOMAINLEN]; /* if fail: log reason, and depending on config also take action * and drop the zone, eg. it is gone from memory, set zone_expired */ dname_str(z->name, zstr); @@ -8436,7 +8434,7 @@ zonemd_lookup_dnskey(struct auth_zone* z, struct module_env* env) qinfo.local_alias = NULL; if(verbosity >= VERB_ALGO) { char buf1[512]; - char buf2[LDNS_MAX_DOMAINLEN+1]; + char buf2[LDNS_MAX_DOMAINLEN]; dname_str(z->name, buf2); snprintf(buf1, sizeof(buf1), "auth zone %s: lookup %s " "for zonemd verification", buf2, @@ -8584,3 +8582,161 @@ void auth_zones_pickup_zonemd_verify(struct auth_zones* az, } lock_rw_unlock(&az->lock); } + +/** Get memory usage of auth rrset */ +static size_t +auth_rrset_get_mem(struct auth_rrset* rrset) +{ + size_t m = sizeof(*rrset) + packed_rrset_sizeof(rrset->data); + return m; +} + +/** Get memory usage of auth data */ +static size_t +auth_data_get_mem(struct auth_data* node) +{ + size_t m = sizeof(*node) + node->namelen; + struct auth_rrset* rrset; + for(rrset = node->rrsets; rrset; rrset = rrset->next) { + m += auth_rrset_get_mem(rrset); + } + return m; +} + +/** Get memory usage of auth zone */ +static size_t +auth_zone_get_mem(struct auth_zone* z) +{ + size_t m = sizeof(*z) + z->namelen; + struct auth_data* node; + if(z->zonefile) + m += strlen(z->zonefile)+1; + RBTREE_FOR(node, struct auth_data*, &z->data) { + m += auth_data_get_mem(node); + } + if(z->rpz) + m += rpz_get_mem(z->rpz); + return m; +} + +/** Get memory usage of list of auth addr */ +static size_t +auth_addrs_get_mem(struct auth_addr* list) +{ + size_t m = 0; + struct auth_addr* a; + for(a = list; a; a = a->next) { + m += sizeof(*a); + } + return m; +} + +/** Get memory usage of list of primaries for auth xfer */ +static size_t +auth_primaries_get_mem(struct auth_master* list) +{ + size_t m = 0; + struct auth_master* n; + for(n = list; n; n = n->next) { + m += sizeof(*n); + m += auth_addrs_get_mem(n->list); + if(n->host) + m += strlen(n->host)+1; + if(n->file) + m += strlen(n->file)+1; + } + return m; +} + +/** Get memory usage or list of auth chunks */ +static size_t +auth_chunks_get_mem(struct auth_chunk* list) +{ + size_t m = 0; + struct auth_chunk* chunk; + for(chunk = list; chunk; chunk = chunk->next) { + m += sizeof(*chunk) + chunk->len; + } + return m; +} + +/** Get memory usage of auth xfer */ +static size_t +auth_xfer_get_mem(struct auth_xfer* xfr) +{ + size_t m = sizeof(*xfr) + xfr->namelen; + + /* auth_nextprobe */ + m += comm_timer_get_mem(xfr->task_nextprobe->timer); + + /* auth_probe */ + m += auth_primaries_get_mem(xfr->task_probe->masters); + m += comm_point_get_mem(xfr->task_probe->cp); + m += comm_timer_get_mem(xfr->task_probe->timer); + + /* auth_transfer */ + m += auth_chunks_get_mem(xfr->task_transfer->chunks_first); + m += auth_primaries_get_mem(xfr->task_transfer->masters); + m += comm_point_get_mem(xfr->task_transfer->cp); + m += comm_timer_get_mem(xfr->task_transfer->timer); + + /* allow_notify_list */ + m += auth_primaries_get_mem(xfr->allow_notify_list); + + return m; +} + +/** Get memory usage of auth zones ztree */ +static size_t +az_ztree_get_mem(struct auth_zones* az) +{ + size_t m = 0; + struct auth_zone* z; + RBTREE_FOR(z, struct auth_zone*, &az->ztree) { + lock_rw_rdlock(&z->lock); + m += auth_zone_get_mem(z); + lock_rw_unlock(&z->lock); + } + return m; +} + +/** Get memory usage of auth zones xtree */ +static size_t +az_xtree_get_mem(struct auth_zones* az) +{ + size_t m = 0; + struct auth_xfer* xfr; + RBTREE_FOR(xfr, struct auth_xfer*, &az->xtree) { + lock_basic_lock(&xfr->lock); + m += auth_xfer_get_mem(xfr); + lock_basic_unlock(&xfr->lock); + } + return m; +} + +size_t auth_zones_get_mem(struct auth_zones* zones) +{ + size_t m; + if(!zones) return 0; + m = sizeof(*zones); + lock_rw_rdlock(&zones->rpz_lock); + lock_rw_rdlock(&zones->lock); + m += az_ztree_get_mem(zones); + m += az_xtree_get_mem(zones); + lock_rw_unlock(&zones->lock); + lock_rw_unlock(&zones->rpz_lock); + return m; +} + +void xfr_disown_tasks(struct auth_xfer* xfr, struct worker* worker) +{ + if(xfr->task_nextprobe->worker == worker) { + xfr_nextprobe_disown(xfr); + } + if(xfr->task_probe->worker == worker) { + xfr_probe_disown(xfr); + } + if(xfr->task_transfer->worker == worker) { + xfr_transfer_disown(xfr); + } +} diff --git a/services/authzone.h b/services/authzone.h index 07614ed82963..722781a063a8 100644 --- a/services/authzone.h +++ b/services/authzone.h @@ -70,7 +70,8 @@ struct auth_chunk; * Authoritative zones, shared. */ struct auth_zones { - /** lock on the authzone trees */ + /** lock on the authzone trees. It is locked after views, respip, + * local_zones and before fwds and stubs. */ lock_rw_type lock; /** rbtree of struct auth_zone */ rbtree_type ztree; @@ -78,10 +79,6 @@ struct auth_zones { rbtree_type xtree; /** do we have downstream enabled */ int have_downstream; - /** number of queries upstream */ - size_t num_query_up; - /** number of queries downstream */ - size_t num_query_down; /** first auth zone containing rpz item in linked list */ struct auth_zone* rpz_first; /** rw lock for rpz linked list, needed when iterating or editing linked @@ -211,7 +208,9 @@ struct auth_xfer { * one of the tasks. * Once it has the task assigned to it, the worker can access the * other elements of the task structure without a lock, because that - * is necessary for the eventloop and callbacks from that. */ + * is necessary for the eventloop and callbacks from that. + * The auth_zone->lock is locked before this lock. + */ lock_basic_type lock; /** zone name, in uncompressed wireformat */ @@ -787,4 +786,33 @@ void auth_zonemd_dnskey_lookup_callback(void* arg, int rcode, void auth_zones_pickup_zonemd_verify(struct auth_zones* az, struct module_env* env); +/** Get memory usage for auth zones. The routine locks and unlocks + * for reading. */ +size_t auth_zones_get_mem(struct auth_zones* zones); + +/** + * Initial pick up of the auth zone nextprobe timeout and that turns + * into further zone transfer work, if any. Also sets the lease time. + * @param x: xfer structure, locked by caller. + * @param env: environment of the worker that picks up the task. + */ +void auth_xfer_pickup_initial_zone(struct auth_xfer* x, + struct module_env* env); + +/** + * Delete auth xfer structure + * @param xfr: delete this xfer and its tasks. + */ +void auth_xfer_delete(struct auth_xfer* xfr); + +/** + * Disown tasks from the xfr that belong to this worker. + * Only tasks for the worker in question, the comm point and timer + * delete functions need to run in the thread of that worker to be + * able to delete the callback from the event base. + * @param xfr: xfr structure + * @param worker: the worker for which to stop tasks. + */ +void xfr_disown_tasks(struct auth_xfer* xfr, struct worker* worker); + #endif /* SERVICES_AUTHZONE_H */ diff --git a/services/cache/dns.c b/services/cache/dns.c index 7ab63bacf492..351b3568c80b 100644 --- a/services/cache/dns.c +++ b/services/cache/dns.c @@ -1056,8 +1056,9 @@ dns_cache_lookup(struct module_env* env, int dns_cache_store(struct module_env* env, struct query_info* msgqinf, - struct reply_info* msgrep, int is_referral, time_t leeway, int pside, - struct regional* region, uint32_t flags, time_t qstarttime) + struct reply_info* msgrep, int is_referral, time_t leeway, int pside, + struct regional* region, uint32_t flags, time_t qstarttime, + int is_valrec) { struct reply_info* rep = NULL; if(SERVE_EXPIRED) { @@ -1065,7 +1066,7 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf, * useful expired record exists. */ struct msgreply_entry* e = msg_cache_lookup(env, msgqinf->qname, msgqinf->qname_len, msgqinf->qtype, - msgqinf->qclass, flags, 0, 0); + msgqinf->qclass, flags, 0, 1); if(e) { struct reply_info* cached = e->entry.data; if(cached->ttl < *env->now @@ -1079,7 +1080,43 @@ dns_cache_store(struct module_env* env, struct query_info* msgqinf, * one and let the validator manage caching. */ && cached->security != sec_status_bogus && (env->need_to_validate && - msgrep->security == sec_status_unchecked)) { + msgrep->security == sec_status_unchecked) + /* Exceptions to that rule are: + * o recursions that don't need validation but + * need to update the cache for coherence + * (delegation information while iterating, + * DNSKEY and DS lookups from validator) + * o explicit RRSIG queries that are not + * validated. */ + && !is_valrec + && msgqinf->qtype != LDNS_RR_TYPE_RRSIG) { + if((int)FLAGS_GET_RCODE(msgrep->flags) != + LDNS_RCODE_NOERROR && + (int)FLAGS_GET_RCODE(msgrep->flags) != + LDNS_RCODE_NXDOMAIN) { + /* The current response has an + * erroneous rcode. Adjust norec time + * so that additional lookups are not + * performed for some time. */ + verbose(VERB_ALGO, "set " + "serve-expired-norec-ttl for " + "response in cache"); + cached->serve_expired_norec_ttl = + NORR_TTL + *env->now; + if(env->cfg->serve_expired_ttl_reset && + cached->serve_expired_ttl + < *env->now + + env->cfg->serve_expired_ttl) { + /* Reset serve-expired-ttl for + * valid response in cache. */ + verbose(VERB_ALGO, "reset " + "serve-expired-ttl " + "for response in cache"); + cached->serve_expired_ttl = + *env->now + + env->cfg->serve_expired_ttl; + } + } verbose(VERB_ALGO, "a validated expired entry " "could be overwritten, skip caching " "the new message at this stage"); diff --git a/services/cache/dns.h b/services/cache/dns.h index 1dd537d2bd5d..8aa6b44bc341 100644 --- a/services/cache/dns.h +++ b/services/cache/dns.h @@ -90,11 +90,14 @@ struct dns_msg { * (See DNSCACHE_STORE_xxx flags). * @param qstarttime: time when the query was started, and thus when the * delegations were looked up. + * @param is_valrec: if the query is validation recursion and does not get + * dnssec validation itself. * @return 0 on alloc error (out of memory). */ int dns_cache_store(struct module_env* env, struct query_info* qinf, struct reply_info* rep, int is_referral, time_t leeway, int pside, - struct regional* region, uint32_t flags, time_t qstarttime); + struct regional* region, uint32_t flags, time_t qstarttime, + int is_valrec); /** * Store message in the cache. Stores in message cache and rrset cache. diff --git a/services/cache/infra.c b/services/cache/infra.c index 66b17c1218ea..cf999422d002 100644 --- a/services/cache/infra.c +++ b/services/cache/infra.c @@ -52,24 +52,6 @@ #include "util/config_file.h" #include "iterator/iterator.h" -/** Timeout when only a single probe query per IP is allowed. */ -#define PROBE_MAXRTO 12000 /* in msec */ - -/** number of timeouts for a type when the domain can be blocked ; - * even if another type has completely rtt maxed it, the different type - * can do this number of packets (until those all timeout too) */ -#define TIMEOUT_COUNT_MAX 3 - -/** Minus 1000 because that is outside of the RTTBAND, so - * blacklisted servers stay blacklisted if this is chosen. - * If USEFUL_SERVER_TOP_TIMEOUT is below 1000 (configured via RTT_MAX_TIMEOUT, - * infra-cache-max-rtt) change it to just above the RTT_BAND. */ -#define STILL_USEFUL_TIMEOUT ( \ - USEFUL_SERVER_TOP_TIMEOUT < 1000 || \ - USEFUL_SERVER_TOP_TIMEOUT - 1000 <= RTT_BAND \ - ?RTT_BAND + 1 \ - :USEFUL_SERVER_TOP_TIMEOUT - 1000) - /** ratelimit value for delegation point */ int infra_dp_ratelimit = 0; @@ -82,6 +64,20 @@ int infra_ip_ratelimit = 0; * For clients with a valid DNS Cookie. */ int infra_ip_ratelimit_cookie = 0; +/** Minus 1000 because that is outside of the RTTBAND, so + * blacklisted servers stay blacklisted if this is chosen. + * If USEFUL_SERVER_TOP_TIMEOUT is below 1000 (configured via RTT_MAX_TIMEOUT, + * infra-cache-max-rtt) change it to just above the RTT_BAND. */ +int +still_useful_timeout() +{ + return + USEFUL_SERVER_TOP_TIMEOUT < 1000 || + USEFUL_SERVER_TOP_TIMEOUT - 1000 <= RTT_BAND + ?RTT_BAND + 1 + :USEFUL_SERVER_TOP_TIMEOUT - 1000; +} + size_t infra_sizefunc(void* k, void* ATTR_UNUSED(d)) { @@ -165,7 +161,7 @@ rate_deldatafunc(void* d, void* ATTR_UNUSED(arg)) /** find or create element in domainlimit tree */ static struct domain_limit_data* domain_limit_findcreate( - struct infra_cache* infra, char* name) + struct rbtree_type* domain_limits, char* name) { uint8_t* nm; int labs; @@ -181,8 +177,8 @@ static struct domain_limit_data* domain_limit_findcreate( labs = dname_count_labels(nm); /* can we find it? */ - d = (struct domain_limit_data*)name_tree_find(&infra->domain_limits, - nm, nmlen, labs, LDNS_RR_CLASS_IN); + d = (struct domain_limit_data*)name_tree_find(domain_limits, nm, + nmlen, labs, LDNS_RR_CLASS_IN); if(d) { free(nm); return d; @@ -201,8 +197,8 @@ static struct domain_limit_data* domain_limit_findcreate( d->node.dclass = LDNS_RR_CLASS_IN; d->lim = -1; d->below = -1; - if(!name_tree_insert(&infra->domain_limits, &d->node, nm, nmlen, - labs, LDNS_RR_CLASS_IN)) { + if(!name_tree_insert(domain_limits, &d->node, nm, nmlen, labs, + LDNS_RR_CLASS_IN)) { log_err("duplicate element in domainlimit tree"); free(nm); free(d); @@ -212,19 +208,19 @@ static struct domain_limit_data* domain_limit_findcreate( } /** insert rate limit configuration into lookup tree */ -static int infra_ratelimit_cfg_insert(struct infra_cache* infra, +static int infra_ratelimit_cfg_insert(struct rbtree_type* domain_limits, struct config_file* cfg) { struct config_str2list* p; struct domain_limit_data* d; for(p = cfg->ratelimit_for_domain; p; p = p->next) { - d = domain_limit_findcreate(infra, p->str); + d = domain_limit_findcreate(domain_limits, p->str); if(!d) return 0; d->lim = atoi(p->str2); } for(p = cfg->ratelimit_below_domain; p; p = p->next) { - d = domain_limit_findcreate(infra, p->str); + d = domain_limit_findcreate(domain_limits, p->str); if(!d) return 0; d->below = atoi(p->str2); @@ -232,24 +228,21 @@ static int infra_ratelimit_cfg_insert(struct infra_cache* infra, return 1; } -/** setup domain limits tree (0 on failure) */ -static int -setup_domain_limits(struct infra_cache* infra, struct config_file* cfg) +int +setup_domain_limits(struct rbtree_type* domain_limits, struct config_file* cfg) { - name_tree_init(&infra->domain_limits); - if(!infra_ratelimit_cfg_insert(infra, cfg)) { + name_tree_init(domain_limits); + if(!infra_ratelimit_cfg_insert(domain_limits, cfg)) { return 0; } - name_tree_init_parents(&infra->domain_limits); + name_tree_init_parents(domain_limits); return 1; } /** find or create element in wait limit netblock tree */ static struct wait_limit_netblock_info* -wait_limit_netblock_findcreate(struct infra_cache* infra, char* str, - int cookie) +wait_limit_netblock_findcreate(struct rbtree_type* tree, char* str) { - rbtree_type* tree; struct sockaddr_storage addr; int net; socklen_t addrlen; @@ -261,10 +254,6 @@ wait_limit_netblock_findcreate(struct infra_cache* infra, char* str, } /* can we find it? */ - if(cookie) - tree = &infra->wait_limits_cookie_netblock; - else - tree = &infra->wait_limits_netblock; d = (struct wait_limit_netblock_info*)addr_tree_find(tree, &addr, addrlen, net); if(d) @@ -286,19 +275,21 @@ wait_limit_netblock_findcreate(struct infra_cache* infra, char* str, /** insert wait limit information into lookup tree */ static int -infra_wait_limit_netblock_insert(struct infra_cache* infra, - struct config_file* cfg) +infra_wait_limit_netblock_insert(rbtree_type* wait_limits_netblock, + rbtree_type* wait_limits_cookie_netblock, struct config_file* cfg) { struct config_str2list* p; struct wait_limit_netblock_info* d; for(p = cfg->wait_limit_netblock; p; p = p->next) { - d = wait_limit_netblock_findcreate(infra, p->str, 0); + d = wait_limit_netblock_findcreate(wait_limits_netblock, + p->str); if(!d) return 0; d->limit = atoi(p->str2); } for(p = cfg->wait_limit_cookie_netblock; p; p = p->next) { - d = wait_limit_netblock_findcreate(infra, p->str, 1); + d = wait_limit_netblock_findcreate(wait_limits_cookie_netblock, + p->str); if(!d) return 0; d->limit = atoi(p->str2); @@ -306,16 +297,48 @@ infra_wait_limit_netblock_insert(struct infra_cache* infra, return 1; } -/** setup wait limits tree (0 on failure) */ +/** Add a default wait limit netblock */ static int -setup_wait_limits(struct infra_cache* infra, struct config_file* cfg) +wait_limit_netblock_default(struct rbtree_type* tree, char* str, int limit) { - addr_tree_init(&infra->wait_limits_netblock); - addr_tree_init(&infra->wait_limits_cookie_netblock); - if(!infra_wait_limit_netblock_insert(infra, cfg)) + struct wait_limit_netblock_info* d; + d = wait_limit_netblock_findcreate(tree, str); + if(!d) return 0; - addr_tree_init_parents(&infra->wait_limits_netblock); - addr_tree_init_parents(&infra->wait_limits_cookie_netblock); + d->limit = limit; + return 1; +} + +int +setup_wait_limits(rbtree_type* wait_limits_netblock, + rbtree_type* wait_limits_cookie_netblock, struct config_file* cfg) +{ + addr_tree_init(wait_limits_netblock); + addr_tree_init(wait_limits_cookie_netblock); + + /* Insert defaults */ + /* The loopback address is separated from the rest of the network. */ + /* wait-limit-netblock: 127.0.0.0/8 -1 */ + if(!wait_limit_netblock_default(wait_limits_netblock, "127.0.0.0/8", + -1)) + return 0; + /* wait-limit-netblock: ::1/128 -1 */ + if(!wait_limit_netblock_default(wait_limits_netblock, "::1/128", -1)) + return 0; + /* wait-limit-cookie-netblock: 127.0.0.0/8 -1 */ + if(!wait_limit_netblock_default(wait_limits_cookie_netblock, + "127.0.0.0/8", -1)) + return 0; + /* wait-limit-cookie-netblock: ::1/128 -1 */ + if(!wait_limit_netblock_default(wait_limits_cookie_netblock, + "::1/128", -1)) + return 0; + + if(!infra_wait_limit_netblock_insert(wait_limits_netblock, + wait_limits_cookie_netblock, cfg)) + return 0; + addr_tree_init_parents(wait_limits_netblock); + addr_tree_init_parents(wait_limits_cookie_netblock); return 1; } @@ -348,11 +371,12 @@ infra_create(struct config_file* cfg) return NULL; } /* insert config data into ratelimits */ - if(!setup_domain_limits(infra, cfg)) { + if(!setup_domain_limits(&infra->domain_limits, cfg)) { infra_delete(infra); return NULL; } - if(!setup_wait_limits(infra, cfg)) { + if(!setup_wait_limits(&infra->wait_limits_netblock, + &infra->wait_limits_cookie_netblock, cfg)) { infra_delete(infra); return NULL; } @@ -377,12 +401,29 @@ static void domain_limit_free(rbnode_type* n, void* ATTR_UNUSED(arg)) } } +void +domain_limits_free(struct rbtree_type* domain_limits) +{ + if(!domain_limits) + return; + traverse_postorder(domain_limits, domain_limit_free, NULL); +} + /** delete wait_limit_netblock_info entries */ static void wait_limit_netblock_del(rbnode_type* n, void* ATTR_UNUSED(arg)) { free(n); } +void +wait_limits_free(struct rbtree_type* wait_limits_tree) +{ + if(!wait_limits_tree) + return; + traverse_postorder(wait_limits_tree, wait_limit_netblock_del, + NULL); +} + void infra_delete(struct infra_cache* infra) { @@ -390,12 +431,10 @@ infra_delete(struct infra_cache* infra) return; slabhash_delete(infra->hosts); slabhash_delete(infra->domain_rates); - traverse_postorder(&infra->domain_limits, domain_limit_free, NULL); + domain_limits_free(&infra->domain_limits); slabhash_delete(infra->client_ip_rates); - traverse_postorder(&infra->wait_limits_netblock, - wait_limit_netblock_del, NULL); - traverse_postorder(&infra->wait_limits_cookie_netblock, - wait_limit_netblock_del, NULL); + wait_limits_free(&infra->wait_limits_netblock); + wait_limits_free(&infra->wait_limits_cookie_netblock); free(infra); } @@ -426,7 +465,7 @@ infra_adjust(struct infra_cache* infra, struct config_file* cfg) /* reapply domain limits */ traverse_postorder(&infra->domain_limits, domain_limit_free, NULL); - if(!setup_domain_limits(infra, cfg)) { + if(!setup_domain_limits(&infra->domain_limits, cfg)) { infra_delete(infra); return NULL; } @@ -668,7 +707,7 @@ infra_update_tcp_works(struct infra_cache* infra, if(data->rtt.rto >= RTT_MAX_TIMEOUT) /* do not disqualify this server altogether, it is better * than nothing */ - data->rtt.rto = STILL_USEFUL_TIMEOUT; + data->rtt.rto = still_useful_timeout(); lock_rw_unlock(&e->lock); } @@ -808,7 +847,7 @@ infra_get_lame_rtt(struct infra_cache* infra, && infra->infra_keep_probing) { /* single probe, keep probing */ if(*rtt >= USEFUL_SERVER_TOP_TIMEOUT) - *rtt = STILL_USEFUL_TIMEOUT; + *rtt = still_useful_timeout(); } else if(host->rtt.rto >= PROBE_MAXRTO && timenow < host->probedelay && rtt_notimeout(&host->rtt)*4 <= host->rtt.rto) { /* single probe for this domain, and we are not probing */ @@ -816,15 +855,15 @@ infra_get_lame_rtt(struct infra_cache* infra, if(qtype == LDNS_RR_TYPE_A) { if(host->timeout_A >= TIMEOUT_COUNT_MAX) *rtt = USEFUL_SERVER_TOP_TIMEOUT; - else *rtt = STILL_USEFUL_TIMEOUT; + else *rtt = still_useful_timeout(); } else if(qtype == LDNS_RR_TYPE_AAAA) { if(host->timeout_AAAA >= TIMEOUT_COUNT_MAX) *rtt = USEFUL_SERVER_TOP_TIMEOUT; - else *rtt = STILL_USEFUL_TIMEOUT; + else *rtt = still_useful_timeout(); } else { if(host->timeout_other >= TIMEOUT_COUNT_MAX) *rtt = USEFUL_SERVER_TOP_TIMEOUT; - else *rtt = STILL_USEFUL_TIMEOUT; + else *rtt = still_useful_timeout(); } } /* expired entry */ @@ -832,7 +871,7 @@ infra_get_lame_rtt(struct infra_cache* infra, /* see if this can be a re-probe of an unresponsive server */ if(host->rtt.rto >= USEFUL_SERVER_TOP_TIMEOUT) { lock_rw_unlock(&e->lock); - *rtt = STILL_USEFUL_TIMEOUT; + *rtt = still_useful_timeout(); *lame = 0; *dnsseclame = 0; *reclame = 0; @@ -1081,7 +1120,8 @@ int infra_ratelimit_inc(struct infra_cache* infra, uint8_t* name, lock_rw_unlock(&entry->lock); if(premax <= lim && max > lim) { - char buf[257], qnm[257], ts[12], cs[12], ip[128]; + char buf[LDNS_MAX_DOMAINLEN], qnm[LDNS_MAX_DOMAINLEN]; + char ts[12], cs[12], ip[128]; dname_str(name, buf); dname_str(qinfo->qname, qnm); sldns_wire2str_type_buf(qinfo->qtype, ts, sizeof(ts)); diff --git a/services/cache/infra.h b/services/cache/infra.h index 1a88bbb94da8..903048cb286e 100644 --- a/services/cache/infra.h +++ b/services/cache/infra.h @@ -52,6 +52,19 @@ struct slabhash; struct config_file; +/** number of timeouts for a type when the domain can be blocked ; + * even if another type has completely rtt maxed it, the different type + * can do this number of packets (until those all timeout too) */ +#define TIMEOUT_COUNT_MAX 3 + + +/** Timeout when only a single probe query per IP is allowed. + * Any RTO above this number is considered a probe. + * It is synchronized (caped) with USEFUL_SERVER_TOP_TIMEOUT so that probing + * keeps working even if that configurable number drops below the default + * 12000 ms of probing. */ +extern int PROBE_MAXRTO; + /** * Host information kept for every server, per zone. */ @@ -502,4 +515,22 @@ void infra_wait_limit_inc(struct infra_cache* infra, struct comm_reply* rep, void infra_wait_limit_dec(struct infra_cache* infra, struct comm_reply* rep, struct config_file* cfg); +/** setup wait limits tree (0 on failure) */ +int setup_wait_limits(struct rbtree_type* wait_limits_netblock, + struct rbtree_type* wait_limits_cookie_netblock, + struct config_file* cfg); + +/** Free the wait limits and wait cookie limits tree. */ +void wait_limits_free(struct rbtree_type* wait_limits_tree); + +/** setup domain limits tree (0 on failure) */ +int setup_domain_limits(struct rbtree_type* domain_limits, + struct config_file* cfg); + +/** Free the domain limits tree. */ +void domain_limits_free(struct rbtree_type* domain_limits); + +/** exported for unit test */ +int still_useful_timeout(); + #endif /* SERVICES_CACHE_INFRA_H */ diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c index 5dbac3650aaf..26efadc151a1 100644 --- a/services/listen_dnsport.c +++ b/services/listen_dnsport.c @@ -703,7 +703,10 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto, { int s = -1; char* err; -#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) || defined(IPV6_V6ONLY) || defined(IP_TRANSPARENT) || defined(IP_BINDANY) || defined(IP_FREEBIND) || defined(SO_BINDANY) +#if defined(SO_REUSEADDR) || defined(SO_REUSEPORT) \ + || defined(IPV6_V6ONLY) || defined(IP_TRANSPARENT) \ + || defined(IP_BINDANY) || defined(IP_FREEBIND) \ + || defined(SO_BINDANY) || defined(TCP_NODELAY) int on = 1; #endif #ifdef HAVE_SYSTEMD @@ -1031,7 +1034,7 @@ err: * Create socket from getaddrinfo results */ static int -make_sock(int stype, const char* ifname, const char* port, +make_sock(int stype, const char* ifname, int port, struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd, int* reuseport, int transparent, int tcp_mss, int nodelay, int freebind, int use_systemd, int dscp, struct unbound_socket* ub_sock, @@ -1039,9 +1042,11 @@ make_sock(int stype, const char* ifname, const char* port, { struct addrinfo *res = NULL; int r, s, inuse, noproto; + char portbuf[32]; + snprintf(portbuf, sizeof(portbuf), "%d", port); hints->ai_socktype = stype; *noip6 = 0; - if((r=getaddrinfo(ifname, port, hints, &res)) != 0 || !res) { + if((r=getaddrinfo(ifname, portbuf, hints, &res)) != 0 || !res) { #ifdef USE_WINSOCK if(r == EAI_NONAME && hints->ai_family == AF_INET6){ *noip6 = 1; /* 'Host not found' for IP6 on winXP */ @@ -1049,7 +1054,7 @@ make_sock(int stype, const char* ifname, const char* port, } #endif log_err("node %s:%s getaddrinfo: %s %s", - ifname?ifname:"default", port, gai_strerror(r), + ifname?ifname:"default", portbuf, gai_strerror(r), #ifdef EAI_SYSTEM (r==EAI_SYSTEM?(char*)strerror(errno):"") #else @@ -1103,7 +1108,7 @@ make_sock(int stype, const char* ifname, const char* port, /** make socket and first see if ifname contains port override info */ static int -make_sock_port(int stype, const char* ifname, const char* port, +make_sock_port(int stype, const char* ifname, int port, struct addrinfo *hints, int v6only, int* noip6, size_t rcv, size_t snd, int* reuseport, int transparent, int tcp_mss, int nodelay, int freebind, int use_systemd, int dscp, struct unbound_socket* ub_sock, @@ -1112,23 +1117,22 @@ make_sock_port(int stype, const char* ifname, const char* port, char* s = strchr(ifname, '@'); if(s) { /* override port with ifspec@port */ - char p[16]; + int port; char newif[128]; if((size_t)(s-ifname) >= sizeof(newif)) { log_err("ifname too long: %s", ifname); *noip6 = 0; return -1; } - if(strlen(s+1) >= sizeof(p)) { - log_err("portnumber too long: %s", ifname); + port = atoi(s+1); + if(port < 0 || 0 == port || port > 65535) { + log_err("invalid portnumber in interface: %s", ifname); *noip6 = 0; return -1; } (void)strlcpy(newif, ifname, sizeof(newif)); newif[s-ifname] = 0; - (void)strlcpy(p, s+1, sizeof(p)); - p[strlen(s+1)]=0; - return make_sock(stype, newif, p, hints, v6only, noip6, rcv, + return make_sock(stype, newif, port, hints, v6only, noip6, rcv, snd, reuseport, transparent, tcp_mss, nodelay, freebind, use_systemd, dscp, ub_sock, additional); } @@ -1237,26 +1241,6 @@ set_recvpktinfo(int s, int family) return 1; } -/** see if interface is ssl, its port number == the ssl port number */ -static int -if_is_ssl(const char* ifname, const char* port, int ssl_port, - struct config_strlist* tls_additional_port) -{ - struct config_strlist* s; - char* p = strchr(ifname, '@'); - if(!p && atoi(port) == ssl_port) - return 1; - if(p && atoi(p+1) == ssl_port) - return 1; - for(s = tls_additional_port; s; s = s->next) { - if(p && atoi(p+1) == atoi(s->str)) - return 1; - if(!p && atoi(port) == atoi(s->str)) - return 1; - } - return 0; -} - /** * Helper for ports_open. Creates one interface (or NULL for default). * @param ifname: The interface ip address. @@ -1265,7 +1249,7 @@ if_is_ssl(const char* ifname, const char* port, int ssl_port, * @param do_udp: if udp should be used. * @param do_tcp: if tcp should be used. * @param hints: for getaddrinfo. family and flags have to be set by caller. - * @param port: Port number to use (as string). + * @param port: Port number to use. * @param list: list of open ports, appended to, changed to point to list head. * @param rcv: receive buffer size for UDP * @param snd: send buffer size for UDP @@ -1291,7 +1275,7 @@ if_is_ssl(const char* ifname, const char* port, int ssl_port, */ static int ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, - struct addrinfo *hints, const char* port, struct listen_port** list, + struct addrinfo *hints, int port, struct listen_port** list, size_t rcv, size_t snd, int ssl_port, struct config_strlist* tls_additional_port, int https_port, struct config_strlist* proxy_protocol_port, @@ -1300,12 +1284,18 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, int quic_port, int http_notls_downstream, int sock_queue_timeout) { int s, noip6=0; + int is_ssl = if_is_ssl(ifname, port, ssl_port, tls_additional_port); int is_https = if_is_https(ifname, port, https_port); int is_dnscrypt = if_is_dnscrypt(ifname, port, dnscrypt_port); int is_pp2 = if_is_pp2(ifname, port, proxy_protocol_port); - int nodelay = is_https && http2_nodelay; - struct unbound_socket* ub_sock; int is_doq = if_is_quic(ifname, port, quic_port); + /* Always set TCP_NODELAY on TLS connection as it speeds up the TLS + * handshake. DoH had already such option so we respect it. + * Otherwise the server waits before sending more handshake data for + * the client ACK (Nagle's algorithm), which is delayed because the + * client waits for more data before ACKing (delayed ACK). */ + int nodelay = is_https?http2_nodelay:is_ssl; + struct unbound_socket* ub_sock; const char* add = NULL; if(!do_udp && !do_tcp) @@ -1324,6 +1314,12 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, } } + /* Check if both UDP and TCP ports should be open. + * In the case of encrypted channels, probably an unencrypted channel + * at the same port is not desired. */ + if((is_ssl || is_https) && !is_doq) do_udp = do_auto = 0; + if((is_doq) && !(is_https || is_ssl)) do_tcp = 0; + if(do_auto) { ub_sock = calloc(1, sizeof(struct unbound_socket)); if(!ub_sock) @@ -1369,13 +1365,11 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, } else if(is_doq) { udp_port_type = listen_type_doq; add = "doq"; - if(((strchr(ifname, '@') && - atoi(strchr(ifname, '@')+1) == 53) || - (!strchr(ifname, '@') && atoi(port) == 53))) { - log_err("DNS over QUIC is not allowed on " - "port 53. Port 53 is for DNS " - "datagrams. Error for " - "interface '%s'.", ifname); + if(if_listens_on(ifname, port, 53, NULL)) { + log_err("DNS over QUIC is strictly not " + "allowed on port 53 as per RFC 9250. " + "Port 53 is for DNS datagrams. Error " + "for interface '%s'.", ifname); free(ub_sock->addr); free(ub_sock); return 0; @@ -1423,8 +1417,6 @@ ports_create_if(const char* ifname, int do_auto, int do_udp, int do_tcp, } } if(do_tcp) { - int is_ssl = if_is_ssl(ifname, port, ssl_port, - tls_additional_port); enum listen_type port_type; ub_sock = calloc(1, sizeof(struct unbound_socket)); if(!ub_sock) @@ -1523,9 +1515,10 @@ listen_create(struct comm_base* base, struct listen_port* ports, size_t bufsize, int tcp_accept_count, int tcp_idle_timeout, int harden_large_queries, uint32_t http_max_streams, char* http_endpoint, int http_notls, struct tcl_list* tcp_conn_limit, - void* sslctx, struct dt_env* dtenv, struct doq_table* doq_table, - struct ub_randstate* rnd, const char* ssl_service_key, - const char* ssl_service_pem, struct config_file* cfg, + void* dot_sslctx, void* doh_sslctx, void* quic_sslctx, + struct dt_env* dtenv, + struct doq_table* doq_table, + struct ub_randstate* rnd,struct config_file* cfg, comm_point_callback_type* cb, void *cb_arg) { struct listen_dnsport* front = (struct listen_dnsport*) @@ -1558,8 +1551,7 @@ listen_create(struct comm_base* base, struct listen_port* ports, #endif cp = comm_point_create_doq(base, ports->fd, front->udp_buff, cb, cb_arg, ports->socket, - doq_table, rnd, ssl_service_key, - ssl_service_pem, cfg); + doq_table, rnd, quic_sslctx, cfg); } else if(ports->ftype == listen_type_tcp || ports->ftype == listen_type_tcp_dnscrypt) { cp = comm_point_create_tcp(base, ports->fd, @@ -1578,7 +1570,7 @@ listen_create(struct comm_base* base, struct listen_port* ports, ports->ftype, ports->pp2_enabled, cb, cb_arg, ports->socket); if(ports->ftype == listen_type_http) { - if(!sslctx && !http_notls) { + if(!doh_sslctx && !http_notls) { log_warn("HTTPS port configured, but " "no TLS tls-service-key or " "tls-service-pem set"); @@ -1620,10 +1612,15 @@ listen_create(struct comm_base* base, struct listen_port* ports, (ports->ftype == listen_type_udpancil) || (ports->ftype == listen_type_tcp_dnscrypt) || (ports->ftype == listen_type_udp_dnscrypt) || - (ports->ftype == listen_type_udpancil_dnscrypt)) + (ports->ftype == listen_type_udpancil_dnscrypt)) { cp->ssl = NULL; - else - cp->ssl = sslctx; + } else if(ports->ftype == listen_type_doq) { + cp->ssl = quic_sslctx; + } else if(ports->ftype == listen_type_http) { + cp->ssl = doh_sslctx; + } else { + cp->ssl = dot_sslctx; + } cp->dtenv = dtenv; cp->do_not_close = 1; #ifdef USE_DNSCRYPT @@ -1887,8 +1884,6 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs, struct addrinfo hints; int i, do_ip4, do_ip6; int do_tcp, do_auto; - char portbuf[32]; - snprintf(portbuf, sizeof(portbuf), "%d", cfg->port); do_ip4 = cfg->do_ip4; do_ip6 = cfg->do_ip6; do_tcp = cfg->do_tcp; @@ -1934,12 +1929,11 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs, return NULL; } now = after; - snprintf(portbuf, sizeof(portbuf), "%d", extraport); if(do_ip6) { hints.ai_family = AF_INET6; if(!ports_create_if("::0", do_auto, cfg->do_udp, do_tcp, - &hints, portbuf, &list, + &hints, extraport, &list, cfg->so_rcvbuf, cfg->so_sndbuf, cfg->ssl_port, cfg->tls_additional_port, cfg->https_port, @@ -1958,7 +1952,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs, hints.ai_family = AF_INET; if(!ports_create_if("0.0.0.0", do_auto, cfg->do_udp, do_tcp, - &hints, portbuf, &list, + &hints, extraport, &list, cfg->so_rcvbuf, cfg->so_sndbuf, cfg->ssl_port, cfg->tls_additional_port, cfg->https_port, @@ -1980,7 +1974,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs, hints.ai_family = AF_INET6; if(!ports_create_if(do_auto?"::0":"::1", do_auto, cfg->do_udp, do_tcp, - &hints, portbuf, &list, + &hints, cfg->port, &list, cfg->so_rcvbuf, cfg->so_sndbuf, cfg->ssl_port, cfg->tls_additional_port, cfg->https_port, cfg->proxy_protocol_port, @@ -1998,7 +1992,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs, hints.ai_family = AF_INET; if(!ports_create_if(do_auto?"0.0.0.0":"127.0.0.1", do_auto, cfg->do_udp, do_tcp, - &hints, portbuf, &list, + &hints, cfg->port, &list, cfg->so_rcvbuf, cfg->so_sndbuf, cfg->ssl_port, cfg->tls_additional_port, cfg->https_port, cfg->proxy_protocol_port, @@ -2018,7 +2012,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs, continue; hints.ai_family = AF_INET6; if(!ports_create_if(ifs[i], 0, cfg->do_udp, - do_tcp, &hints, portbuf, &list, + do_tcp, &hints, cfg->port, &list, cfg->so_rcvbuf, cfg->so_sndbuf, cfg->ssl_port, cfg->tls_additional_port, cfg->https_port, cfg->proxy_protocol_port, @@ -2036,7 +2030,7 @@ listening_ports_open(struct config_file* cfg, char** ifs, int num_ifs, continue; hints.ai_family = AF_INET; if(!ports_create_if(ifs[i], 0, cfg->do_udp, - do_tcp, &hints, portbuf, &list, + do_tcp, &hints, cfg->port, &list, cfg->so_rcvbuf, cfg->so_sndbuf, cfg->ssl_port, cfg->tls_additional_port, cfg->https_port, cfg->proxy_protocol_port, @@ -4598,10 +4592,9 @@ doq_alpn_select_cb(SSL* ATTR_UNUSED(ssl), const unsigned char** out, return SSL_TLSEXT_ERR_ALERT_FATAL; } -/** create new tls session for server doq connection */ -static SSL_CTX* -doq_ctx_server_setup(struct doq_server_socket* doq_socket) +void* quic_sslctx_create(char* key, char* pem, char* verifypem) { +#ifdef HAVE_NGTCP2 char* sid_ctx = "unbound server"; #ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT SSL_QUIC_METHOD* quic_method; @@ -4611,6 +4604,16 @@ doq_ctx_server_setup(struct doq_server_socket* doq_socket) log_crypto_err("Could not SSL_CTX_new"); return NULL; } + if(!key || key[0] == 0) { + log_err("doq: error, no tls-service-key file specified"); + SSL_CTX_free(ctx); + return NULL; + } + if(!pem || pem[0] == 0) { + log_err("doq: error, no tls-service-pem file specified"); + SSL_CTX_free(ctx); + return NULL; + } SSL_CTX_set_options(ctx, (SSL_OP_ALL & ~SSL_OP_DONT_INSERT_EMPTY_FRAGMENTS) | SSL_OP_SINGLE_ECDH_USE | @@ -4623,43 +4626,37 @@ doq_ctx_server_setup(struct doq_server_socket* doq_socket) SSL_CTX_set_alpn_select_cb(ctx, doq_alpn_select_cb, NULL); #endif SSL_CTX_set_default_verify_paths(ctx); - if(!SSL_CTX_use_certificate_chain_file(ctx, - doq_socket->ssl_service_pem)) { - log_err("doq: error for cert file: %s", - doq_socket->ssl_service_pem); + if(!SSL_CTX_use_certificate_chain_file(ctx, pem)) { + log_err("doq: error for cert file: %s", pem); log_crypto_err("doq: error in " "SSL_CTX_use_certificate_chain_file"); SSL_CTX_free(ctx); return NULL; } - if(!SSL_CTX_use_PrivateKey_file(ctx, doq_socket->ssl_service_key, - SSL_FILETYPE_PEM)) { - log_err("doq: error for private key file: %s", - doq_socket->ssl_service_key); + if(!SSL_CTX_use_PrivateKey_file(ctx, key, SSL_FILETYPE_PEM)) { + log_err("doq: error for private key file: %s", key); log_crypto_err("doq: error in SSL_CTX_use_PrivateKey_file"); SSL_CTX_free(ctx); return NULL; } if(!SSL_CTX_check_private_key(ctx)) { - log_err("doq: error for key file: %s", - doq_socket->ssl_service_key); + log_err("doq: error for key file: %s", key); log_crypto_err("doq: error in SSL_CTX_check_private_key"); SSL_CTX_free(ctx); return NULL; } SSL_CTX_set_session_id_context(ctx, (void*)sid_ctx, strlen(sid_ctx)); - if(doq_socket->ssl_verify_pem && doq_socket->ssl_verify_pem[0]) { - if(!SSL_CTX_load_verify_locations(ctx, - doq_socket->ssl_verify_pem, NULL)) { + if(verifypem && verifypem[0]) { + if(!SSL_CTX_load_verify_locations(ctx, verifypem, NULL)) { log_err("doq: error for verify pem file: %s", - doq_socket->ssl_verify_pem); + verifypem); log_crypto_err("doq: error in " "SSL_CTX_load_verify_locations"); SSL_CTX_free(ctx); return NULL; } SSL_CTX_set_client_CA_list(ctx, SSL_load_client_CA_file( - doq_socket->ssl_verify_pem)); + verifypem)); SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER| SSL_VERIFY_CLIENT_ONCE| SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); @@ -4672,7 +4669,7 @@ doq_ctx_server_setup(struct doq_server_socket* doq_socket) SSL_CTX_free(ctx); return NULL; } -#else +#else /* HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT */ /* The quic_method needs to remain valid during the SSL_CTX * lifetime, so we allocate it. It is freed with the * doq_server_socket. */ @@ -4690,6 +4687,10 @@ doq_ctx_server_setup(struct doq_server_socket* doq_socket) SSL_CTX_set_quic_method(ctx, doq_socket->quic_method); #endif return ctx; +#else /* HAVE_NGTCP2 */ + (void)key; (void)pem; (void)verifypem; + return NULL; +#endif /* HAVE_NGTCP2 */ } /** Get the ngtcp2_conn from ssl userdata of type ngtcp2_conn_ref */ @@ -4720,16 +4721,6 @@ doq_ssl_server_setup(SSL_CTX* ctx, struct doq_conn* conn) return ssl; } -/** setup the doq_socket server tls context */ -int -doq_socket_setup_ctx(struct doq_server_socket* doq_socket) -{ - doq_socket->ctx = doq_ctx_server_setup(doq_socket); - if(!doq_socket->ctx) - return 0; - return 1; -} - int doq_conn_setup(struct doq_conn* conn, uint8_t* scid, size_t scidlen, uint8_t* ocid, size_t ocidlen, const uint8_t* token, size_t tokenlen) diff --git a/services/listen_dnsport.h b/services/listen_dnsport.h index c29f4d72b0a2..f6275f805fba 100644 --- a/services/listen_dnsport.h +++ b/services/listen_dnsport.h @@ -194,12 +194,12 @@ int resolve_interface_names(char** ifs, int num_ifs, * @param http_endpoint: HTTP endpoint to service queries on * @param http_notls: no TLS for http downstream * @param tcp_conn_limit: TCP connection limit info. - * @param sslctx: nonNULL if ssl context. + * @param dot_sslctx: nonNULL if dot ssl context. + * @param doh_sslctx: nonNULL if doh ssl context. + * @param quic_sslctx: nonNULL if quic ssl context. * @param dtenv: nonNULL if dnstap enabled. * @param doq_table: the doq connection table, with shared information. * @param rnd: random state. - * @param ssl_service_key: the SSL service key file. - * @param ssl_service_pem: the SSL service pem file. * @param cfg: config file struct. * @param cb: callback function when a request arrives. It is passed * the packet and user argument. Return true to send a reply. @@ -211,9 +211,10 @@ listen_create(struct comm_base* base, struct listen_port* ports, size_t bufsize, int tcp_accept_count, int tcp_idle_timeout, int harden_large_queries, uint32_t http_max_streams, char* http_endpoint, int http_notls, struct tcl_list* tcp_conn_limit, - void* sslctx, struct dt_env* dtenv, struct doq_table* doq_table, - struct ub_randstate* rnd, const char* ssl_service_key, - const char* ssl_service_pem, struct config_file* cfg, + void* dot_sslctx, void* doh_sslctx, void* quic_sslctx, + struct dt_env* dtenv, + struct doq_table* doq_table, + struct ub_randstate* rnd,struct config_file* cfg, comm_point_callback_type* cb, void *cb_arg); /** @@ -512,6 +513,15 @@ struct doq_table { size_t current_size; }; +/** + * create SSL context for QUIC + * @param key: private key file. + * @param pem: public key cert. + * @param verifypem: if nonNULL, verifylocation file. + * return SSL_CTX* or NULL on failure (logged). + */ +void* quic_sslctx_create(char* key, char* pem, char* verifypem); + /** create doq table */ struct doq_table* doq_table_create(struct config_file* cfg, struct ub_randstate* rnd); @@ -712,9 +722,6 @@ int doq_timer_cmp(const void* key1, const void* key2); /** compare function of doq_stream */ int doq_stream_cmp(const void* key1, const void* key2); -/** setup the doq_socket server tls context */ -int doq_socket_setup_ctx(struct doq_server_socket* doq_socket); - /** setup the doq connection callbacks, and settings. */ int doq_conn_setup(struct doq_conn* conn, uint8_t* scid, size_t scidlen, uint8_t* ocid, size_t ocidlen, const uint8_t* token, size_t tokenlen); diff --git a/services/localzone.c b/services/localzone.c index d21e0c48aedb..9ea98c250907 100644 --- a/services/localzone.c +++ b/services/localzone.c @@ -223,7 +223,7 @@ lz_enter_zone_dname(struct local_zones* zones, uint8_t* nm, size_t len, lock_rw_wrlock(&z->lock); if(!rbtree_insert(&zones->ztree, &z->node)) { struct local_zone* oldz; - char str[256]; + char str[LDNS_MAX_DOMAINLEN]; dname_str(nm, str); log_warn("duplicate local-zone %s", str); lock_rw_unlock(&z->lock); @@ -943,6 +943,16 @@ int local_zone_enter_defaults(struct local_zones* zones, struct config_file* cfg log_err("out of memory adding default zone"); return 0; } + /* resolver.arpa. zone (RFC 9462) */ + if(!add_empty_default(zones, cfg, "resolver.arpa.")) { + log_err("out of memory adding default zone"); + return 0; + } + /* service.arpa. zone (draft-ietf-dnssd-srp-25) */ + if(!add_empty_default(zones, cfg, "service.arpa.")) { + log_err("out of memory adding default zone"); + return 0; + } /* onion. zone (RFC 7686) */ if(!add_empty_default(zones, cfg, "onion.")) { log_err("out of memory adding default zone"); @@ -1765,7 +1775,7 @@ lz_inform_print(struct local_zone* z, struct query_info* qinfo, struct sockaddr_storage* addr, socklen_t addrlen) { char ip[128], txt[512]; - char zname[LDNS_MAX_DOMAINLEN+1]; + char zname[LDNS_MAX_DOMAINLEN]; uint16_t port = ntohs(((struct sockaddr_in*)addr)->sin_port); dname_str(z->name, zname); addr_to_str(addr, addrlen, ip, sizeof(ip)); @@ -1875,7 +1885,7 @@ local_zones_answer(struct local_zones* zones, struct module_env* env, return 0; } if(z && verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(z->name, zname); verbose(VERB_ALGO, "using localzone %s %s from view %s", zname, local_zone_type2str(lzt), view->name); @@ -1897,7 +1907,7 @@ local_zones_answer(struct local_zones* zones, struct module_env* env, z->override_tree, &tag, tagname, num_tags); lock_rw_unlock(&zones->lock); if(z && verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(z->name, zname); verbose(VERB_ALGO, "using localzone %s %s", zname, local_zone_type2str(lzt)); @@ -2210,3 +2220,35 @@ void local_zones_del_data(struct local_zones* zones, lock_rw_unlock(&z->lock); } + +/** Get memory usage for local_zone */ +static size_t +local_zone_get_mem(struct local_zone* z) +{ + size_t m = sizeof(*z); + lock_rw_rdlock(&z->lock); + m += z->namelen + z->taglen + regional_get_mem(z->region); + lock_rw_unlock(&z->lock); + return m; +} + +size_t local_zones_get_mem(struct local_zones* zones) +{ + struct local_zone* z; + size_t m; + if(!zones) return 0; + m = sizeof(*zones); + lock_rw_rdlock(&zones->lock); + RBTREE_FOR(z, struct local_zone*, &zones->ztree) { + m += local_zone_get_mem(z); + } + lock_rw_unlock(&zones->lock); + return m; +} + +void local_zones_swap_tree(struct local_zones* zones, struct local_zones* data) +{ + rbtree_type oldtree = zones->ztree; + zones->ztree = data->ztree; + data->ztree = oldtree; +} diff --git a/services/localzone.h b/services/localzone.h index 6f0f28b12422..66102fd98f7e 100644 --- a/services/localzone.h +++ b/services/localzone.h @@ -642,6 +642,20 @@ local_zone_enter_rr(struct local_zone* z, uint8_t* nm, size_t nmlen, struct local_data* local_zone_find_data(struct local_zone* z, uint8_t* nm, size_t nmlen, int nmlabs); +/** Get memory usage for local_zones tree. The routine locks and unlocks + * the tree for reading. */ +size_t local_zones_get_mem(struct local_zones* zones); + +/** + * Swap internal tree with preallocated entries. Caller should manage + * the locks. + * @param zones: the local zones structure. + * @param data: the data structure used to take elements from. This contains + * the old elements on return. + */ +void local_zones_swap_tree(struct local_zones* zones, + struct local_zones* data); + /** Enter a new zone; returns with WRlock * Made public for unit testing * @param zones: the local zones tree diff --git a/services/mesh.c b/services/mesh.c index d512ab3d32d4..8a52fe4a6466 100644 --- a/services/mesh.c +++ b/services/mesh.c @@ -77,6 +77,20 @@ #include <netdb.h> #endif +/** Compare two views by name */ +static int +view_name_compare(const char* v_a, const char* v_b) +{ + if(v_a == NULL && v_b == NULL) + return 0; + /* The NULL name is smaller than if the name is set. */ + if(v_a == NULL) + return -1; + if(v_b == NULL) + return 1; + return strcmp(v_a, v_b); +} + /** * Compare two response-ip client info entries for the purpose of mesh state * compare. It returns 0 if ci_a and ci_b are considered equal; otherwise @@ -132,12 +146,14 @@ client_info_compare(const struct respip_client_info* ci_a, } if(ci_a->tag_datas != ci_b->tag_datas) return ci_a->tag_datas < ci_b->tag_datas ? -1 : 1; - if(ci_a->view != ci_b->view) - return ci_a->view < ci_b->view ? -1 : 1; - /* For the unbound daemon these should be non-NULL and identical, - * but we check that just in case. */ - if(ci_a->respip_set != ci_b->respip_set) - return ci_a->respip_set < ci_b->respip_set ? -1 : 1; + if(ci_a->view || ci_a->view_name || ci_b->view || ci_b->view_name) { + /* Compare the views by name. */ + cmp = view_name_compare( + (ci_a->view?ci_a->view->name:ci_a->view_name), + (ci_b->view?ci_b->view->name:ci_b->view_name)); + if(cmp != 0) + return cmp; + } return 0; } @@ -214,6 +230,9 @@ mesh_create(struct module_stack* stack, struct module_env* env) mesh->stats_dropped = 0; mesh->ans_expired = 0; mesh->ans_cachedb = 0; + mesh->num_queries_discard_timeout = 0; + mesh->num_queries_wait_limit = 0; + mesh->num_dns_error_reports = 0; mesh->max_reply_states = env->cfg->num_queries_per_thread; mesh->max_forever_states = (mesh->max_reply_states+1)/2; #ifndef S_SPLINT_S @@ -424,7 +443,7 @@ void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo, verbose(VERB_ALGO, "Too many queries waiting from the IP. " "dropping incoming query."); comm_point_drop_reply(rep); - mesh->stats_dropped++; + mesh->num_queries_wait_limit++; return; } if(!unique) @@ -868,6 +887,78 @@ void mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e, mesh_run(mesh, e->qstate->mesh_info, event, e); } +/** copy strlist to region */ +static struct config_strlist* +cfg_region_strlist_copy(struct regional* region, struct config_strlist* list) +{ + struct config_strlist* result = NULL, *last = NULL, *s = list; + while(s) { + struct config_strlist* n = regional_alloc_zero(region, + sizeof(*n)); + if(!n) + return NULL; + n->str = regional_strdup(region, s->str); + if(!n->str) + return NULL; + if(last) + last->next = n; + else result = n; + last = n; + s = s->next; + } + return result; +} + +/** Copy the client info to the query region. */ +static struct respip_client_info* +mesh_copy_client_info(struct regional* region, struct respip_client_info* cinfo) +{ + size_t i; + struct respip_client_info* client_info; + client_info = regional_alloc_init(region, cinfo, sizeof(*cinfo)); + if(!client_info) + return NULL; + /* Copy the client_info so that if the configuration changes, + * then the data stays valid. */ + if(cinfo->taglist) { + client_info->taglist = regional_alloc_init(region, cinfo->taglist, + cinfo->taglen); + if(!client_info->taglist) + return NULL; + } + if(cinfo->tag_actions) { + client_info->tag_actions = regional_alloc_init(region, cinfo->tag_actions, + cinfo->tag_actions_size); + if(!client_info->tag_actions) + return NULL; + } + if(cinfo->tag_datas) { + client_info->tag_datas = regional_alloc_zero(region, + sizeof(struct config_strlist*)*cinfo->tag_datas_size); + if(!client_info->tag_datas) + return NULL; + for(i=0; i<cinfo->tag_datas_size; i++) { + if(cinfo->tag_datas[i]) { + client_info->tag_datas[i] = cfg_region_strlist_copy( + region, cinfo->tag_datas[i]); + if(!client_info->tag_datas[i]) + return NULL; + } + } + } + if(cinfo->view) { + /* Do not copy the view pointer but store a name instead. + * The name is looked up later when done, this means that + * the view tree can be changed, by reloads. */ + client_info->view = NULL; + client_info->view_name = regional_strdup(region, + cinfo->view->name); + if(!client_info->view_name) + return NULL; + } + return client_info; +} + struct mesh_state* mesh_state_create(struct module_env* env, struct query_info* qinfo, struct respip_client_info* cinfo, uint16_t qflags, int prime, @@ -908,8 +999,7 @@ mesh_state_create(struct module_env* env, struct query_info* qinfo, return NULL; } if(cinfo) { - mstate->s.client_info = regional_alloc_init(region, cinfo, - sizeof(*cinfo)); + mstate->s.client_info = mesh_copy_client_info(region, cinfo); if(!mstate->s.client_info) { alloc_reg_release(env->alloc, region); return NULL; @@ -1489,10 +1579,121 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep, &r->query_reply.client_addr, r->query_reply.client_addrlen, duration, 0, r_buffer, (m->s.env->cfg->log_destaddr?(void*)r->query_reply.c->socket->addr:NULL), - r->query_reply.c->type); + r->query_reply.c->type, r->query_reply.c->ssl); } } +/** + * Generate the DNS Error Report (RFC9567). + * If there is an EDE attached for this reply and there was a Report-Channel + * EDNS0 option from the upstream, fire up a report query. + * @param qstate: module qstate. + * @param rep: prepared reply to be sent. + */ +static void dns_error_reporting(struct module_qstate* qstate, + struct reply_info* rep) +{ + struct query_info qinfo; + struct mesh_state* sub; + struct module_qstate* newq; + uint8_t buf[LDNS_MAX_DOMAINLEN]; + size_t count = 0; + int written; + size_t expected_length; + struct edns_option* opt; + sldns_ede_code reason_bogus = LDNS_EDE_NONE; + sldns_rr_type qtype = qstate->qinfo.qtype; + uint8_t* qname = qstate->qinfo.qname; + size_t qname_len = qstate->qinfo.qname_len-1; /* skip the trailing \0 */ + uint8_t* agent_domain; + size_t agent_domain_len; + + /* We need a valid reporting agent; + * this is based on qstate->edns_opts_back_in that will probably have + * the latest reporting agent we found while iterating */ + opt = edns_opt_list_find(qstate->edns_opts_back_in, + LDNS_EDNS_REPORT_CHANNEL); + if(!opt) return; + agent_domain_len = opt->opt_len; + agent_domain = opt->opt_data; + if(dname_valid(agent_domain, agent_domain_len) < 3) { + /* The agent domain needs to be a valid dname that is not the + * root; from RFC9567. */ + return; + } + + /* Get the EDE generated from the mesh state, these are mostly + * validator errors. If other errors are produced in the future (e.g., + * RPZ) we would not want them to result in error reports. */ + reason_bogus = errinf_to_reason_bogus(qstate); + if(rep && ((reason_bogus == LDNS_EDE_DNSSEC_BOGUS && + rep->reason_bogus != LDNS_EDE_NONE) || + reason_bogus == LDNS_EDE_NONE)) { + reason_bogus = rep->reason_bogus; + } + if(reason_bogus == LDNS_EDE_NONE || + /* other, does not make sense without the text that comes + * with it */ + reason_bogus == LDNS_EDE_OTHER) return; + + /* Synthesize the error report query in the format: + * "_er.$qtype.$qname.$ede._er.$reporting-agent-domain" */ + /* First check if the static length parts fit in the buffer. + * That is everything except for qtype and ede that need to be + * converted to decimal and checked further on. */ + expected_length = 4/*_er*/+qname_len+4/*_er*/+agent_domain_len; + if(expected_length > LDNS_MAX_DOMAINLEN) goto skip; + + memmove(buf+count, "\3_er", 4); + count += 4; + + written = snprintf((char*)buf+count, LDNS_MAX_DOMAINLEN-count, + "X%d", qtype); + expected_length += written; + /* Skip on error, truncation or long expected length */ + if(written < 0 || (size_t)written >= LDNS_MAX_DOMAINLEN-count || + expected_length > LDNS_MAX_DOMAINLEN ) goto skip; + /* Put in the label length */ + *(buf+count) = (char)(written - 1); + count += written; + + memmove(buf+count, qname, qname_len); + count += qname_len; + + written = snprintf((char*)buf+count, LDNS_MAX_DOMAINLEN-count, + "X%d", reason_bogus); + expected_length += written; + /* Skip on error, truncation or long expected length */ + if(written < 0 || (size_t)written >= LDNS_MAX_DOMAINLEN-count || + expected_length > LDNS_MAX_DOMAINLEN ) goto skip; + *(buf+count) = (char)(written - 1); + count += written; + + memmove(buf+count, "\3_er", 4); + count += 4; + + /* Copy the agent domain */ + memmove(buf+count, agent_domain, agent_domain_len); + count += agent_domain_len; + + qinfo.qname = buf; + qinfo.qname_len = count; + qinfo.qtype = LDNS_RR_TYPE_TXT; + qinfo.qclass = qstate->qinfo.qclass; + qinfo.local_alias = NULL; + + log_query_info(VERB_ALGO, "DNS Error Reporting: generating report " + "query for", &qinfo); + if(mesh_add_sub(qstate, &qinfo, BIT_RD, 0, 0, &newq, &sub)) { + qstate->env->mesh->num_dns_error_reports++; + } + return; +skip: + verbose(VERB_ALGO, "DNS Error Reporting: report query qname too long; " + "skip"); + return; +} + void mesh_query_done(struct mesh_state* mstate) { struct mesh_reply* r; @@ -1510,8 +1711,10 @@ void mesh_query_done(struct mesh_state* mstate) } if(mstate->s.return_rcode == LDNS_RCODE_SERVFAIL || (rep && FLAGS_GET_RCODE(rep->flags) == LDNS_RCODE_SERVFAIL)) { - /* we are SERVFAILing; check for expired answer here */ - mesh_serve_expired_callback(mstate); + if(mstate->s.env->cfg->serve_expired) { + /* we are SERVFAILing; check for expired answer here */ + mesh_respond_serve_expired(mstate); + } if((mstate->reply_list || mstate->cb_list) && mstate->s.env->cfg->log_servfail && !mstate->s.env->cfg->val_log_squelch) { @@ -1519,6 +1722,10 @@ void mesh_query_done(struct mesh_state* mstate) if(err) { log_err("%s", err); } } } + + if(mstate->reply_list && mstate->s.env->cfg->dns_error_reporting) + dns_error_reporting(&mstate->s, rep); + for(r = mstate->reply_list; r; r = r->next) { struct timeval old; timeval_subtract(&old, mstate->s.env->now_tv, &r->start_time); @@ -1540,7 +1747,7 @@ void mesh_query_done(struct mesh_state* mstate) http2_stream_remove_mesh_state(r->h2_stream); comm_point_drop_reply(&r->query_reply); mstate->reply_list = reply_list; - mstate->s.env->mesh->stats_dropped++; + mstate->s.env->mesh->num_queries_discard_timeout++; continue; } @@ -1682,6 +1889,25 @@ struct mesh_state* mesh_area_find(struct mesh_area* mesh, return result; } +/** remove mesh state callback */ +int mesh_state_del_cb(struct mesh_state* s, mesh_cb_func_type cb, void* cb_arg) +{ + struct mesh_cb* r, *prev = NULL; + r = s->cb_list; + while(r) { + if(r->cb == cb && r->cb_arg == cb_arg) { + /* Delete this entry. */ + /* It was allocated in the s.region, so no free. */ + if(prev) prev->next = r->next; + else s->cb_list = r->next; + return 1; + } + prev = r; + r = r->next; + } + return 0; +} + int mesh_state_add_cb(struct mesh_state* s, struct edns_data* edns, sldns_buffer* buf, mesh_cb_func_type cb, void* cb_arg, uint16_t qid, uint16_t qflags) @@ -2029,6 +2255,8 @@ mesh_stats_clear(struct mesh_area* mesh) { if(!mesh) return; + mesh->num_query_authzone_up = 0; + mesh->num_query_authzone_down = 0; mesh->replies_sent = 0; mesh->replies_sum_wait.tv_sec = 0; mesh->replies_sum_wait.tv_usec = 0; @@ -2042,6 +2270,9 @@ mesh_stats_clear(struct mesh_area* mesh) memset(&mesh->ans_rcode[0], 0, sizeof(size_t)*UB_STATS_RCODE_NUM); memset(&mesh->rpz_action[0], 0, sizeof(size_t)*UB_STATS_RPZ_ACTION_NUM); mesh->ans_nodata = 0; + mesh->num_queries_discard_timeout = 0; + mesh->num_queries_wait_limit = 0; + mesh->num_dns_error_reports = 0; } size_t @@ -2143,7 +2374,8 @@ apply_respip_action(struct module_qstate* qstate, return 1; if(!respip_rewrite_reply(qinfo, cinfo, rep, encode_repp, actinfo, - alias_rrset, 0, qstate->region, az, NULL)) + alias_rrset, 0, qstate->region, az, NULL, qstate->env->views, + qstate->env->respip_set)) return 0; /* xxx_deny actions mean dropping the reply, unless the original reply @@ -2177,7 +2409,7 @@ mesh_serve_expired_callback(void* arg) struct timeval tv = {0, 0}; int must_validate = (!(qstate->query_flags&BIT_CD) || qstate->env->cfg->ignore_cd) && qstate->env->need_to_validate; - int i = 0; + int i = 0, for_count; int is_expired; if(!qstate->serve_expired_data) return; verbose(VERB_ALGO, "Serve expired: Trying to reply with expired data"); @@ -2190,15 +2422,21 @@ mesh_serve_expired_callback(void* arg) "Serve expired: Not allowed to look into cache for stale"); return; } - /* The following while is used instead of the `goto lookup_cache` - * like in the worker. */ - while(1) { + /* The following for is used instead of the `goto lookup_cache` + * like in the worker. This loop should get max 2 passes if we need to + * do any aliasing. */ + for(for_count = 0; for_count < 2; for_count++) { fptr_ok(fptr_whitelist_serve_expired_lookup( qstate->serve_expired_data->get_cached_answer)); msg = (*qstate->serve_expired_data->get_cached_answer)(qstate, lookup_qinfo, &is_expired); - if(!msg) + if(!msg || (FLAGS_GET_RCODE(msg->rep->flags) != LDNS_RCODE_NOERROR + && FLAGS_GET_RCODE(msg->rep->flags) != LDNS_RCODE_NXDOMAIN + && FLAGS_GET_RCODE(msg->rep->flags) != LDNS_RCODE_YXDOMAIN)) { + /* We don't care for cached failure answers at this + * stage. */ return; + } /* Reset these in case we pass a second time from here. */ encode_rep = msg->rep; memset(&actinfo, 0, sizeof(actinfo)); @@ -2212,7 +2450,8 @@ mesh_serve_expired_callback(void* arg) } else if(partial_rep && !respip_merge_cname(partial_rep, &qstate->qinfo, msg->rep, qstate->client_info, must_validate, &encode_rep, qstate->region, - qstate->env->auth_zones)) { + qstate->env->auth_zones, qstate->env->views, + qstate->env->respip_set)) { return; } if(!encode_rep || alias_rrset) { @@ -2270,7 +2509,7 @@ mesh_serve_expired_callback(void* arg) http2_stream_remove_mesh_state(r->h2_stream); comm_point_drop_reply(&r->query_reply); mstate->reply_list = reply_list; - mstate->s.env->mesh->stats_dropped++; + mstate->s.env->mesh->num_queries_discard_timeout++; continue; } @@ -2366,3 +2605,25 @@ int mesh_jostle_exceeded(struct mesh_area* mesh) return 0; return 1; } + +void mesh_remove_callback(struct mesh_area* mesh, struct query_info* qinfo, + uint16_t qflags, mesh_cb_func_type cb, void* cb_arg) +{ + struct mesh_state* s = NULL; + s = mesh_area_find(mesh, NULL, qinfo, qflags&(BIT_RD|BIT_CD), 0, 0); + if(!s) return; + if(!mesh_state_del_cb(s, cb, cb_arg)) return; + + /* It was in the list and removed. */ + log_assert(mesh->num_reply_addrs > 0); + mesh->num_reply_addrs--; + if(!s->reply_list && !s->cb_list) { + /* was a reply state, not anymore */ + log_assert(mesh->num_reply_states > 0); + mesh->num_reply_states--; + } + if(!s->reply_list && !s->cb_list && + s->super_set.count == 0) { + mesh->num_detached_states++; + } +} diff --git a/services/mesh.h b/services/mesh.h index 26ececbe6210..fd17c05da6d4 100644 --- a/services/mesh.h +++ b/services/mesh.h @@ -90,6 +90,11 @@ struct mesh_area { /** rbtree of all current queries (mesh_state.node)*/ rbtree_type all; + /** number of queries for unbound's auth_zones, upstream query */ + size_t num_query_authzone_up; + /** number of queries for unbound's auth_zones, downstream answers */ + size_t num_query_authzone_down; + /** count of the total number of mesh_reply entries */ size_t num_reply_addrs; /** count of the number of mesh_states that have mesh_replies @@ -132,6 +137,12 @@ struct mesh_area { size_t ans_nodata; /** (extended stats) type of applied RPZ action */ size_t rpz_action[UB_STATS_RPZ_ACTION_NUM]; + /** stats, number of queries removed due to discard-timeout */ + size_t num_queries_discard_timeout; + /** stats, number of queries removed due to wait-limit */ + size_t num_queries_wait_limit; + /** stats, number of dns error reports generated */ + size_t num_dns_error_reports; /** backup of query if other operations recurse and need the * network buffers */ @@ -697,4 +708,17 @@ int mesh_jostle_exceeded(struct mesh_area* mesh); */ void mesh_respond_serve_expired(struct mesh_state* mstate); +/** + * Remove callback from mesh. Removes the callback from the state. + * The state itself is left to run. Searches for the pointer values. + * + * @param mesh: the mesh. + * @param qinfo: query from client. + * @param qflags: flags from client query. + * @param cb: callback function. + * @param cb_arg: callback user arg. + */ +void mesh_remove_callback(struct mesh_area* mesh, struct query_info* qinfo, + uint16_t qflags, mesh_cb_func_type cb, void* cb_arg); + #endif /* SERVICES_MESH_H */ diff --git a/services/outside_network.c b/services/outside_network.c index 58f1e6d586aa..0d7ec890573b 100644 --- a/services/outside_network.c +++ b/services/outside_network.c @@ -262,12 +262,14 @@ pick_outgoing_tcp(struct pending_tcp* pend, struct waiting_tcp* w, int s) /** get TCP file descriptor for address, returns -1 on failure, * tcp_mss is 0 or maxseg size to set for TCP packets. */ int -outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss, int dscp) +outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, + int tcp_mss, int dscp, int nodelay) { int s; int af; char* err; -#if defined(SO_REUSEADDR) || defined(IP_BIND_ADDRESS_NO_PORT) +#if defined(SO_REUSEADDR) || defined(IP_BIND_ADDRESS_NO_PORT) \ + || defined(TCP_NODELAY) int on = 1; #endif #ifdef INET6 @@ -320,6 +322,18 @@ outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, int tcp_mss, " setsockopt(.. IP_BIND_ADDRESS_NO_PORT ..) failed"); } #endif /* IP_BIND_ADDRESS_NO_PORT */ + if(nodelay) { +#if defined(IPPROTO_TCP) && defined(TCP_NODELAY) + if(setsockopt(s, IPPROTO_TCP, TCP_NODELAY, (void*)&on, + (socklen_t)sizeof(on)) < 0) { + verbose(VERB_ALGO, "outgoing tcp:" + " setsockopt(.. TCP_NODELAY ..) failed"); + } +#else + verbose(VERB_ALGO, "outgoing tcp:" + " setsockopt(.. TCP_NODELAY ..) unsupported"); +#endif /* defined(IPPROTO_TCP) && defined(TCP_NODELAY) */ + } return s; } @@ -649,7 +663,8 @@ outnet_tcp_take_into_use(struct waiting_tcp* w) } /* open socket */ - s = outnet_get_tcp_fd(&w->addr, w->addrlen, w->outnet->tcp_mss, w->outnet->ip_dscp); + s = outnet_get_tcp_fd(&w->addr, w->addrlen, w->outnet->tcp_mss, + w->outnet->ip_dscp, w->ssl_upstream); if(s == -1) return 0; @@ -1054,7 +1069,7 @@ reuse_move_writewait_away(struct outside_network* outnet, if(verbosity >= VERB_CLIENT && pend->query->pkt_len > 12+2+2 && LDNS_QDCOUNT(pend->query->pkt) > 0 && dname_valid(pend->query->pkt+12, pend->query->pkt_len-12)) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(pend->query->pkt+12, buf); verbose(VERB_CLIENT, "reuse_move_writewait_away current %s %d bytes were written", buf, (int)pend->c->tcp_write_byte_count); @@ -1079,7 +1094,7 @@ reuse_move_writewait_away(struct outside_network* outnet, if(verbosity >= VERB_CLIENT && w->pkt_len > 12+2+2 && LDNS_QDCOUNT(w->pkt) > 0 && dname_valid(w->pkt+12, w->pkt_len-12)) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(w->pkt+12, buf); verbose(VERB_CLIENT, "reuse_move_writewait_away item %s", buf); } @@ -2825,7 +2840,7 @@ serviced_perturb_qname(struct ub_randstate* rnd, uint8_t* qbuf, size_t len) lablen = *d++; } if(verbosity >= VERB_ALGO) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; dname_str(qbuf+10, buf); verbose(VERB_ALGO, "qname perturbed to %s", buf); } @@ -3718,7 +3733,8 @@ outnet_comm_point_for_tcp(struct outside_network* outnet, sldns_buffer* query, int timeout, int ssl, char* host) { struct comm_point* cp; - int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss, outnet->ip_dscp); + int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss, + outnet->ip_dscp, ssl); if(fd == -1) { return 0; } @@ -3793,7 +3809,8 @@ outnet_comm_point_for_http(struct outside_network* outnet, { /* cp calls cb with err=NETEVENT_DONE when transfer is done */ struct comm_point* cp; - int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss, outnet->ip_dscp); + int fd = outnet_get_tcp_fd(to_addr, to_addrlen, outnet->tcp_mss, + outnet->ip_dscp, ssl); if(fd == -1) { return 0; } diff --git a/services/outside_network.h b/services/outside_network.h index 467c81f60ca2..0a77e3388ddc 100644 --- a/services/outside_network.h +++ b/services/outside_network.h @@ -743,9 +743,11 @@ void reuse_write_wait_remove(struct reuse_tcp* reuse, struct waiting_tcp* w); void reuse_write_wait_push_back(struct reuse_tcp* reuse, struct waiting_tcp* w); /** get TCP file descriptor for address, returns -1 on failure, - * tcp_mss is 0 or maxseg size to set for TCP packets. */ + * tcp_mss is 0 or maxseg size to set for TCP packets, + * nodelay (TCP_NODELAY) should be set for TLS connections to speed up the TLS + * handshake.*/ int outnet_get_tcp_fd(struct sockaddr_storage* addr, socklen_t addrlen, - int tcp_mss, int dscp); + int tcp_mss, int dscp, int nodelay); /** * Create udp commpoint suitable for sending packets to the destination. diff --git a/services/rpz.c b/services/rpz.c index 3b92ee53837e..df39e75b0596 100644 --- a/services/rpz.c +++ b/services/rpz.c @@ -666,7 +666,7 @@ rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname, int newzone = 0; if(a == RPZ_INVALID_ACTION) { - char str[255+1]; + char str[LDNS_MAX_DOMAINLEN]; if(rrtype == LDNS_RR_TYPE_SOA || rrtype == LDNS_RR_TYPE_NS || rrtype == LDNS_RR_TYPE_DNAME || rrtype == LDNS_RR_TYPE_DNSKEY || @@ -739,7 +739,7 @@ rpz_insert_local_zones_trigger(struct local_zones* lz, uint8_t* dname, static void rpz_log_dname(char const* msg, uint8_t* dname, size_t dname_len) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; (void)dname_len; dname_str(dname, buf); verbose(VERB_ALGO, "rpz: %s: <%s>", msg, buf); @@ -1062,7 +1062,7 @@ rpz_insert_response_ip_trigger(struct rpz* r, uint8_t* dname, size_t dnamelen, if(a == RPZ_INVALID_ACTION || rpz_action_to_respip_action(a) == respip_invalid) { - char str[255+1]; + char str[LDNS_MAX_DOMAINLEN]; dname_str(dname, str); verbose(VERB_ALGO, "rpz: respip trigger, %s skipping unsupported action: %s", str, rpz_action_to_string(a)); @@ -1633,7 +1633,7 @@ log_rpz_apply(char* trigger, uint8_t* dname, struct addr_tree_node* addrnode, struct comm_reply* repinfo, struct module_qstate* ms, char* log_name) { char ip[128], txt[512], portstr[32]; - char dnamestr[LDNS_MAX_DOMAINLEN+1]; + char dnamestr[LDNS_MAX_DOMAINLEN]; uint16_t port = 0; if(dname) { dname_str(dname, dnamestr); @@ -2427,7 +2427,8 @@ rpz_delegation_point_zone_lookup(struct delegpt* dp, struct local_zones* zones, match->dname = nameserver->name; match->dname_len = nameserver->namelen; if(verbosity >= VERB_ALGO) { - char nm[255+1], zn[255+1]; + char nm[LDNS_MAX_DOMAINLEN]; + char zn[LDNS_MAX_DOMAINLEN]; dname_str(match->dname, nm); dname_str(z->name, zn); if(strcmp(nm, zn) != 0) @@ -2581,7 +2582,7 @@ struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms, } if(verbosity >= VERB_ALGO) { - char nm[255+1], zn[255+1]; + char nm[LDNS_MAX_DOMAINLEN], zn[LDNS_MAX_DOMAINLEN]; dname_str(is->qchase.qname, nm); dname_str(z->name, zn); if(strcmp(zn, nm) != 0) @@ -2758,7 +2759,7 @@ rpz_callback_from_worker_request(struct auth_zones* az, struct module_env* env, } if(verbosity >= VERB_ALGO) { - char nm[255+1], zn[255+1]; + char nm[LDNS_MAX_DOMAINLEN], zn[LDNS_MAX_DOMAINLEN]; dname_str(qinfo->qname, nm); dname_str(z->name, zn); if(strcmp(zn, nm) != 0) @@ -2791,3 +2792,31 @@ void rpz_disable(struct rpz* r) return; r->disabled = 1; } + +/** Get memory usage for clientip_synthesized_rrset. Ignores memory usage + * of locks. */ +static size_t +rpz_clientip_synthesized_set_get_mem(struct clientip_synthesized_rrset* set) +{ + size_t m = sizeof(*set); + lock_rw_rdlock(&set->lock); + m += regional_get_mem(set->region); + lock_rw_unlock(&set->lock); + return m; +} + +size_t rpz_get_mem(struct rpz* r) +{ + size_t m = sizeof(*r); + if(r->taglist) + m += r->taglistlen; + if(r->log_name) + m += strlen(r->log_name) + 1; + m += regional_get_mem(r->region); + m += local_zones_get_mem(r->local_zones); + m += local_zones_get_mem(r->nsdname_zones); + m += respip_set_get_mem(r->respip_set); + m += rpz_clientip_synthesized_set_get_mem(r->client_set); + m += rpz_clientip_synthesized_set_get_mem(r->ns_set); + return m; +} diff --git a/services/rpz.h b/services/rpz.h index 7f409087f772..6b5f17d1e2c1 100644 --- a/services/rpz.h +++ b/services/rpz.h @@ -269,4 +269,11 @@ void rpz_enable(struct rpz* r); */ void rpz_disable(struct rpz* r); +/** + * Get memory usage of rpz. Caller must manage locks. + * @param r: RPZ struct. + * @return memory usage. + */ +size_t rpz_get_mem(struct rpz* r); + #endif /* SERVICES_RPZ_H */ diff --git a/services/view.c b/services/view.c index 72f3643184ee..44b07f3ed1b4 100644 --- a/services/view.c +++ b/services/view.c @@ -43,6 +43,7 @@ #include "services/view.h" #include "services/localzone.h" #include "util/config_file.h" +#include "respip/respip.h" int view_cmp(const void* v1, const void* v2) @@ -66,11 +67,6 @@ views_create(void) return v; } -/* \noop (ignore this comment for doxygen) - * This prototype is defined in in respip.h, but we want to avoid - * unnecessary dependencies */ -void respip_set_delete(struct respip_set *set); - void view_delete(struct view* v) { @@ -247,3 +243,38 @@ void views_print(struct views* v) /* TODO implement print */ (void)v; } + +size_t views_get_mem(struct views* vs) +{ + struct view* v; + size_t m; + if(!vs) return 0; + m = sizeof(struct views); + lock_rw_rdlock(&vs->lock); + RBTREE_FOR(v, struct view*, &vs->vtree) { + m += view_get_mem(v); + } + lock_rw_unlock(&vs->lock); + return m; +} + +size_t view_get_mem(struct view* v) +{ + size_t m = sizeof(*v); + lock_rw_rdlock(&v->lock); + m += getmem_str(v->name); + m += local_zones_get_mem(v->local_zones); + m += respip_set_get_mem(v->respip_set); + lock_rw_unlock(&v->lock); + return m; +} + +void views_swap_tree(struct views* vs, struct views* data) +{ + rbnode_type* oldroot = vs->vtree.root; + size_t oldcount = vs->vtree.count; + vs->vtree.root = data->vtree.root; + vs->vtree.count = data->vtree.count; + data->vtree.root = oldroot; + data->vtree.count = oldcount; +} diff --git a/services/view.h b/services/view.h index 12f7a64e7171..0ff39ed6e75d 100644 --- a/services/view.h +++ b/services/view.h @@ -54,7 +54,8 @@ struct respip_set; * Views storage, shared. */ struct views { - /** lock on the view tree */ + /** lock on the view tree. When locking order, the views lock + * is before the forwards,hints,anchors,localzones lock. */ lock_rw_type lock; /** rbtree of struct view */ rbtree_type vtree; @@ -135,4 +136,27 @@ void views_print(struct views* v); */ struct view* views_find_view(struct views* vs, const char* name, int write); +/** + * Calculate memory usage of views. + * @param vs: the views tree. The routine locks and unlocks the structure + * for reading. + * @return memory in bytes. + */ +size_t views_get_mem(struct views* vs); + +/** + * Calculate memory usage of view. + * @param v: the view. The routine locks and unlocks the structure for reading. + * @return memory in bytes. + */ +size_t view_get_mem(struct view* v); + +/** + * Swap internal tree with preallocated entries. Caller should manage + * the locks. + * @param vs: views tree + * @param data: preallocated information. + */ +void views_swap_tree(struct views* vs, struct views* data); + #endif /* SERVICES_VIEW_H */ diff --git a/sldns/keyraw.c b/sldns/keyraw.c index befe1f722424..90a6e85337c2 100644 --- a/sldns/keyraw.c +++ b/sldns/keyraw.c @@ -195,6 +195,7 @@ void sldns_key_EVP_unload_gost(void) } #endif /* USE_GOST */ +#ifdef USE_DSA /* Retrieve params as BIGNUM from raw buffer */ static int sldns_key_dsa_buf_bignum(unsigned char* key, size_t len, BIGNUM** p, @@ -370,6 +371,7 @@ EVP_PKEY *sldns_key_dsa2pkey_raw(unsigned char* key, size_t len) return evp_key; #endif } +#endif /* USE_DSA */ /* Retrieve params as BIGNUM from raw buffer, n is modulus, e is exponent */ static int diff --git a/sldns/rrdef.c b/sldns/rrdef.c index e81ebb1fc434..9e2100d53843 100644 --- a/sldns/rrdef.c +++ b/sldns/rrdef.c @@ -72,7 +72,7 @@ static const sldns_rdf_type type_nsap_wireformat[] = { LDNS_RDF_TYPE_NSAP }; static const sldns_rdf_type type_nsap_ptr_wireformat[] = { - LDNS_RDF_TYPE_STR + LDNS_RDF_TYPE_UNQUOTED }; static const sldns_rdf_type type_sig_wireformat[] = { LDNS_RDF_TYPE_TYPE, LDNS_RDF_TYPE_ALG, LDNS_RDF_TYPE_INT8, LDNS_RDF_TYPE_INT32, @@ -86,7 +86,7 @@ static const sldns_rdf_type type_px_wireformat[] = { LDNS_RDF_TYPE_INT16, LDNS_RDF_TYPE_DNAME, LDNS_RDF_TYPE_DNAME }; static const sldns_rdf_type type_gpos_wireformat[] = { - LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR, LDNS_RDF_TYPE_STR + LDNS_RDF_TYPE_UNQUOTED, LDNS_RDF_TYPE_UNQUOTED, LDNS_RDF_TYPE_UNQUOTED }; static const sldns_rdf_type type_aaaa_wireformat[] = { LDNS_RDF_TYPE_AAAA }; static const sldns_rdf_type type_loc_wireformat[] = { LDNS_RDF_TYPE_LOC }; @@ -617,6 +617,12 @@ static sldns_rr_descriptor rdata_field_descriptors[] = { {(enum sldns_enum_rr_type)0, "TYPE258", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 }, #endif +{(enum sldns_enum_rr_type)0, "TYPE259", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 }, +{(enum sldns_enum_rr_type)0, "TYPE260", 1, 1, type_0_wireformat, LDNS_RDF_TYPE_NONE, LDNS_RR_NO_COMPRESS, 0 }, + + /* 261 */ + {LDNS_RR_TYPE_RESINFO, "RESINFO", 1, 0, NULL, LDNS_RDF_TYPE_UNQUOTED, LDNS_RR_NO_COMPRESS, 0 }, + /* split in array, no longer contiguous */ #ifdef DRAFT_RRTYPES diff --git a/sldns/rrdef.h b/sldns/rrdef.h index 7cadf7bebfb1..540468889880 100644 --- a/sldns/rrdef.h +++ b/sldns/rrdef.h @@ -229,6 +229,8 @@ enum sldns_enum_rr_type LDNS_RR_TYPE_CAA = 257, /* RFC 6844 */ LDNS_RR_TYPE_AVC = 258, + LDNS_RR_TYPE_RESINFO = 261, /* RFC 9606 */ + /** DNSSEC Trust Authorities */ LDNS_RR_TYPE_TA = 32768, /* RFC 4431, 5074, DNSSEC Lookaside Validation */ @@ -341,6 +343,9 @@ enum sldns_enum_rdf_type /** 8 * 8 bit hex numbers separated by dashes. For EUI64. */ LDNS_RDF_TYPE_EUI64, + /** Character string without quotes. */ + LDNS_RDF_TYPE_UNQUOTED, + /** A non-zero sequence of US-ASCII letters and numbers in lower case. * For CAA. */ @@ -438,6 +443,7 @@ enum sldns_enum_edns_option LDNS_EDNS_PADDING = 12, /* RFC7830 */ LDNS_EDNS_EDE = 15, /* RFC8914 */ LDNS_EDNS_CLIENT_TAG = 16, /* draft-bellis-dnsop-edns-tags-01 */ + LDNS_EDNS_REPORT_CHANNEL = 18, /* RFC9567 */ LDNS_EDNS_UNBOUND_CACHEDB_TESTFRAME_TEST = 65534 }; typedef enum sldns_enum_edns_option sldns_edns_option; diff --git a/sldns/str2wire.c b/sldns/str2wire.c index fdd40e0f2238..becd6d3855c9 100644 --- a/sldns/str2wire.c +++ b/sldns/str2wire.c @@ -365,7 +365,8 @@ static int sldns_rdf_type_maybe_quoted(sldns_rdf_type rdf_type) { return rdf_type == LDNS_RDF_TYPE_STR || - rdf_type == LDNS_RDF_TYPE_LONG_STR; + rdf_type == LDNS_RDF_TYPE_LONG_STR || + rdf_type == LDNS_RDF_TYPE_UNQUOTED; } /** see if rdata is quoted */ @@ -1719,6 +1720,8 @@ int sldns_str2wire_rdf_buf(const char* str, uint8_t* rd, size_t* len, return sldns_str2wire_eui48_buf(str, rd, len); case LDNS_RDF_TYPE_EUI64: return sldns_str2wire_eui64_buf(str, rd, len); + case LDNS_RDF_TYPE_UNQUOTED: + return sldns_str2wire_unquoted_buf(str, rd, len); case LDNS_RDF_TYPE_TAG: return sldns_str2wire_tag_buf(str, rd, len); case LDNS_RDF_TYPE_LONG_STR: @@ -2554,12 +2557,42 @@ int sldns_str2wire_atma_buf(const char* str, uint8_t* rd, size_t* len) { const char* s = str; size_t slen = strlen(str); - size_t dlen = 0; /* number of hexdigits parsed */ + size_t dlen = 0; /* number of hexdigits parsed for hex, + digits for E.164 */ - /* just a hex string with optional dots? */ - /* notimpl e.164 format */ if(slen > LDNS_MAX_RDFLEN*2) return LDNS_WIREPARSE_ERR_LABEL_OVERFLOW; + if(*len < 1) + return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL; + if(*s == 0) { + /* empty string */ + rd[0] = 0; + *len = 1; + return LDNS_WIREPARSE_ERR_OK; + } + if(s[0] == '+') { + rd[0] = 1; /* E.164 format */ + /* digits '0'..'9', with skipped dots. */ + s++; + while(*s) { + if(isspace((unsigned char)*s) || *s == '.') { + s++; + continue; + } + if(*s < '0' || *s > '9') + return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX, s-str); + if(*len < dlen + 2) + return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, + s-str); + rd[dlen+1] = *s++; + dlen++; + } + *len = dlen+1; + return LDNS_WIREPARSE_ERR_OK; + } + + rd[0] = 0; /* AESA format */ + /* hex, with skipped dots. */ while(*s) { if(isspace((unsigned char)*s) || *s == '.') { s++; @@ -2567,17 +2600,17 @@ int sldns_str2wire_atma_buf(const char* str, uint8_t* rd, size_t* len) } if(!isxdigit((unsigned char)*s)) return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_HEX, s-str); - if(*len < dlen/2 + 1) + if(*len < dlen/2 + 2) return RET_ERR(LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL, s-str); if((dlen&1)==0) - rd[dlen/2] = (uint8_t)sldns_hexdigit_to_int(*s++) * 16; - else rd[dlen/2] += sldns_hexdigit_to_int(*s++); + rd[dlen/2 + 1] = (uint8_t)sldns_hexdigit_to_int(*s++) * 16; + else rd[dlen/2 + 1] += sldns_hexdigit_to_int(*s++); dlen++; } if((dlen&1)!=0) return RET_ERR(LDNS_WIREPARSE_ERR_SYNTAX_HEX, s-str); - *len = dlen/2; + *len = dlen/2 + 1; return LDNS_WIREPARSE_ERR_OK; } @@ -2746,6 +2779,11 @@ int sldns_str2wire_eui64_buf(const char* str, uint8_t* rd, size_t* len) return LDNS_WIREPARSE_ERR_OK; } +int sldns_str2wire_unquoted_buf(const char* str, uint8_t* rd, size_t* len) +{ + return sldns_str2wire_str_buf(str, rd, len); +} + int sldns_str2wire_tag_buf(const char* str, uint8_t* rd, size_t* len) { size_t slen = strlen(str); diff --git a/sldns/str2wire.h b/sldns/str2wire.h index 5e4d146d3092..db6528a2f9bf 100644 --- a/sldns/str2wire.h +++ b/sldns/str2wire.h @@ -552,6 +552,15 @@ int sldns_str2wire_eui48_buf(const char* str, uint8_t* rd, size_t* len); int sldns_str2wire_eui64_buf(const char* str, uint8_t* rd, size_t* len); /** + * Convert rdf of type LDNS_RDF_TYPE_UNQUOTED from string to wireformat. + * @param str: the text to convert for this rdata element. + * @param rd: rdata buffer for the wireformat. + * @param len: length of rd buffer on input, used length on output. + * @return 0 on success, error on failure. + */ +int sldns_str2wire_unquoted_buf(const char* str, uint8_t* rd, size_t* len); + +/** * Convert rdf of type LDNS_RDF_TYPE_TAG from string to wireformat. * @param str: the text to convert for this rdata element. * @param rd: rdata buffer for the wireformat. diff --git a/sldns/wire2str.c b/sldns/wire2str.c index ff8399947e8d..1bc5b9cf6e93 100644 --- a/sldns/wire2str.c +++ b/sldns/wire2str.c @@ -1344,6 +1344,8 @@ int sldns_wire2str_rdf_scan(uint8_t** d, size_t* dlen, char** s, size_t* slen, return sldns_wire2str_eui48_scan(d, dlen, s, slen); case LDNS_RDF_TYPE_EUI64: return sldns_wire2str_eui64_scan(d, dlen, s, slen); + case LDNS_RDF_TYPE_UNQUOTED: + return sldns_wire2str_unquoted_scan(d, dlen, s, slen); case LDNS_RDF_TYPE_TAG: return sldns_wire2str_tag_scan(d, dlen, s, slen); case LDNS_RDF_TYPE_LONG_STR: @@ -1870,7 +1872,33 @@ int sldns_wire2str_nsap_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) int sldns_wire2str_atma_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) { - return print_remainder_hex("", d, dl, s, sl); + uint8_t format; + int w = 0; + size_t i; + + if(*dl < 1) return -1; + format = (*d)[0]; + (*d)+=1; + (*dl)-=1; + + if(format == 0) { + /* AESA format (ATM End System Address). */ + return print_remainder_hex("", d, dl, s, sl); + } else if(format == 1) { + /* E.164 format. */ + w += sldns_str_print(s, sl, "+"); + for(i=0; i<*dl; i++) { + if((*d)[i] < '0' || (*d)[0] > '9') + return -1; + w += sldns_str_print(s, sl, "%c", (*d)[i]); + } + (*d) += *dl; + (*dl) = 0; + } else { + /* Unknown format. */ + return -1; + } + return w; } /* internal scan routine that can modify arguments on failure */ @@ -2021,6 +2049,26 @@ int sldns_wire2str_eui64_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) return w; } +int sldns_wire2str_unquoted_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) +{ + int w = 0; + size_t i, len; + if(*dl < 1) return -1; + len = **d; + if(*dl < 1+len) return -1; + (*d)++; + (*dl)--; + for(i=0; i<len; i++) { + if(isspace((unsigned char)(*d)[i]) || (*d)[i] == '(' || + (*d)[i] == ')' || (*d)[i] == '\'') + w += sldns_str_print(s, sl, "\\%c", (char)(*d)[i]); + else w += str_char_print(s, sl, (*d)[i]); + } + (*d)+=len; + (*dl)-=len; + return w; +} + int sldns_wire2str_tag_scan(uint8_t** d, size_t* dl, char** s, size_t* sl) { size_t i, n; diff --git a/sldns/wire2str.h b/sldns/wire2str.h index a7c58b85a5fb..772268b249c9 100644 --- a/sldns/wire2str.h +++ b/sldns/wire2str.h @@ -920,6 +920,19 @@ int sldns_wire2str_eui64_scan(uint8_t** data, size_t* data_len, char** str, size_t* str_len); /** + * Scan wireformat UNQUOTED field to string, with user buffers. + * It shifts the arguments to move along (see sldns_wire2str_pkt_scan). + * @param data: wireformat data. + * @param data_len: length of data buffer. + * @param str: string buffer. + * @param str_len: length of string buffer. + * @return number of characters (except null) needed to print. + * Can return -1 on failure. + */ +int sldns_wire2str_unquoted_scan(uint8_t** data, size_t* data_len, char** str, + size_t* str_len); + +/** * Scan wireformat TAG field to string, with user buffers. * It shifts the arguments to move along (see sldns_wire2str_pkt_scan). * @param data: wireformat data. diff --git a/smallapp/unbound-checkconf.c b/smallapp/unbound-checkconf.c index 6cc5285ecf15..3b7ba758afa5 100644 --- a/smallapp/unbound-checkconf.c +++ b/smallapp/unbound-checkconf.c @@ -342,8 +342,6 @@ interfacechecks(struct config_file* cfg) int i, j, i2, j2; char*** resif = NULL; int* num_resif = NULL; - char portbuf[32]; - snprintf(portbuf, sizeof(portbuf), "%d", cfg->port); if(cfg->num_ifs != 0) { resif = (char***)calloc(cfg->num_ifs, sizeof(char**)); @@ -366,15 +364,19 @@ interfacechecks(struct config_file* cfg) cfg->ifs[i]); } /* check for port combinations that are not supported */ - if(if_is_pp2(resif[i][0], portbuf, cfg->proxy_protocol_port)) { - if(if_is_dnscrypt(resif[i][0], portbuf, + if(if_is_pp2(resif[i][0], cfg->port, cfg->proxy_protocol_port)) { + if(if_is_dnscrypt(resif[i][0], cfg->port, cfg->dnscrypt_port)) { fatal_exit("PROXYv2 and DNSCrypt combination not " "supported!"); - } else if(if_is_https(resif[i][0], portbuf, + } else if(if_is_https(resif[i][0], cfg->port, cfg->https_port)) { fatal_exit("PROXYv2 and DoH combination not " "supported!"); + } else if(if_is_quic(resif[i][0], cfg->port, + cfg->quic_port)) { + fatal_exit("PROXYv2 and DoQ combination not " + "supported!"); } } /* search for duplicates in the returned addresses */ diff --git a/smallapp/unbound-control-setup.sh.in b/smallapp/unbound-control-setup.sh.in index 4a358f6bd09d..c2a79a242972 100644 --- a/smallapp/unbound-control-setup.sh.in +++ b/smallapp/unbound-control-setup.sh.in @@ -204,7 +204,8 @@ fi # remove unused permissions chmod o-rw \ "$SVR_BASE.pem" \ - "$SVR_BASE.key" \ + "$SVR_BASE.key" +chmod g+r,o-rw \ "$CTL_BASE.pem" \ "$CTL_BASE.key" diff --git a/smallapp/unbound-control.c b/smallapp/unbound-control.c index b8479e9ab667..0136b5e4eb67 100644 --- a/smallapp/unbound-control.c +++ b/smallapp/unbound-control.c @@ -109,6 +109,16 @@ usage(void) printf(" That means the caches sizes and\n"); printf(" the number of threads must not\n"); printf(" change between reloads.\n"); + printf(" fast_reload [+dpv] reloads the server but only briefly stops\n"); + printf(" server processing, keeps cache, and changes\n"); + printf(" most options; check unbound-control(8).\n"); + printf(" +d drops running queries to keep consistency\n"); + printf(" on changed options while reloading.\n"); + printf(" +p does not pause threads for even faster\n"); + printf(" reload but less options are supported\n"); + printf(" ; check unbound-control(8).\n"); + printf(" +v verbose output, it will include duration needed.\n"); + printf(" +vv more verbose output, it will include memory needed.\n"); printf(" stats print statistics\n"); printf(" stats_noreset peek at statistics\n"); #ifdef HAVE_SHMGET @@ -222,6 +232,9 @@ static void pr_stats(const char* nm, struct ub_stats_info* s) s->svr.num_queries_cookie_client); PR_UL_NM("num.queries_cookie_invalid", s->svr.num_queries_cookie_invalid); + PR_UL_NM("num.queries_discard_timeout", + s->svr.num_queries_discard_timeout); + PR_UL_NM("num.queries_wait_limit", s->svr.num_queries_wait_limit); PR_UL_NM("num.cachehits", s->svr.num_queries - s->svr.num_queries_missed_cache); PR_UL_NM("num.cachemiss", s->svr.num_queries_missed_cache); @@ -231,12 +244,13 @@ static void pr_stats(const char* nm, struct ub_stats_info* s) PR_UL_NM("num.expired", s->svr.ans_expired); PR_UL_NM("num.recursivereplies", s->mesh_replies_sent); #ifdef USE_DNSCRYPT - PR_UL_NM("num.dnscrypt.crypted", s->svr.num_query_dnscrypt_crypted); - PR_UL_NM("num.dnscrypt.cert", s->svr.num_query_dnscrypt_cert); - PR_UL_NM("num.dnscrypt.cleartext", s->svr.num_query_dnscrypt_cleartext); - PR_UL_NM("num.dnscrypt.malformed", - s->svr.num_query_dnscrypt_crypted_malformed); + PR_UL_NM("num.dnscrypt.crypted", s->svr.num_query_dnscrypt_crypted); + PR_UL_NM("num.dnscrypt.cert", s->svr.num_query_dnscrypt_cert); + PR_UL_NM("num.dnscrypt.cleartext", s->svr.num_query_dnscrypt_cleartext); + PR_UL_NM("num.dnscrypt.malformed", + s->svr.num_query_dnscrypt_crypted_malformed); #endif /* USE_DNSCRYPT */ + PR_UL_NM("num.dns_error_reports", s->svr.num_dns_error_reports); printf("%s.requestlist.avg"SQ"%g\n", nm, (s->svr.num_queries_missed_cache+s->svr.num_queries_prefetch)? (double)s->svr.sum_query_list_size/ diff --git a/smallapp/worker_cb.c b/smallapp/worker_cb.c index 1d71a0945154..92ebe386d269 100644 --- a/smallapp/worker_cb.c +++ b/smallapp/worker_cb.c @@ -256,6 +256,20 @@ void dtio_mainfdcallback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), } #endif +void fast_reload_service_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), + void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} + +int fast_reload_client_callback(struct comm_point* ATTR_UNUSED(c), + void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), + struct comm_reply* ATTR_UNUSED(repinfo)) +{ + log_assert(0); + return 0; +} + #ifdef HAVE_NGTCP2 void doq_client_event_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), void* ATTR_UNUSED(arg)) diff --git a/testcode/checklocks.c b/testcode/checklocks.c index fdc1b8af16de..93bbf70f4af2 100644 --- a/testcode/checklocks.c +++ b/testcode/checklocks.c @@ -64,6 +64,9 @@ static int key_deleted = 0; static ub_thread_key_type thr_debug_key; /** the list of threads, so all threads can be examined. NULL if unused. */ static struct thr_check* thread_infos[THRDEBUG_MAX_THREADS]; +/** stored maximum lock number for threads, when a thread is restarted the + * number is kept track of, because the new locks get new id numbers. */ +static int thread_lockcount[THRDEBUG_MAX_THREADS]; /** do we check locking order */ int check_locking_order = 1; /** the pid of this runset, reasonably unique. */ @@ -698,10 +701,20 @@ open_lockorder(struct thr_check* thr) char buf[24]; time_t t; snprintf(buf, sizeof(buf), "%s.%d", output_name, thr->num); - thr->order_info = fopen(buf, "w"); - if(!thr->order_info) - fatal_exit("could not open %s: %s", buf, strerror(errno)); - thr->locks_created = 0; + thr->locks_created = thread_lockcount[thr->num]; + if(thr->locks_created == 0) { + thr->order_info = fopen(buf, "w"); + if(!thr->order_info) + fatal_exit("could not open %s: %s", buf, strerror(errno)); + } else { + /* There is already a file to append on with the previous + * thread information. */ + thr->order_info = fopen(buf, "a"); + if(!thr->order_info) + fatal_exit("could not open for append %s: %s", buf, strerror(errno)); + return; + } + t = time(NULL); /* write: <time_stamp> <runpid> <thread_num> */ if(fwrite(&t, sizeof(t), 1, thr->order_info) != 1 || @@ -728,6 +741,7 @@ static void* checklock_main(void* arg) if(check_locking_order) open_lockorder(thr); ret = thr->func(thr->arg); + thread_lockcount[thr->num] = thr->locks_created; thread_infos[thr->num] = NULL; if(check_locking_order) fclose(thr->order_info); diff --git a/testcode/do-tests.sh b/testcode/do-tests.sh index 6599f9f66594..4f769c5fdf8f 100755 --- a/testcode/do-tests.sh +++ b/testcode/do-tests.sh @@ -17,6 +17,7 @@ NEED_IPV6='fwd_ancil.tdir fwd_tcp_tc6.tdir stub_udp6.tdir edns_cache.tdir' NEED_NOMINGW='tcp_sigpipe.tdir 07-confroot.tdir 08-host-lib.tdir fwd_ancil.tdir' NEED_DNSCRYPT_PROXY='dnscrypt_queries.tdir dnscrypt_queries_chacha.tdir' NEED_UNSHARE='acl_interface.tdir proxy_protocol.tdir' +NEED_REDIS_SERVER='redis_replica.tdir' # test if dig and ldns-testns are available. test_tool_avail "dig" @@ -52,6 +53,7 @@ for test in `ls -d *.tdir`; do skip_if_in_list $test "$NEED_WHOAMI" "whoami" skip_if_in_list $test "$NEED_DNSCRYPT_PROXY" "dnscrypt-proxy" skip_if_in_list $test "$NEED_UNSHARE" "unshare" + skip_if_in_list $test "$NEED_REDIS_SERVER" "redis-server" if echo $NEED_IPV6 | grep $test >/dev/null; then if test "$HAVE_IPV6" = no; then diff --git a/testcode/doqclient.c b/testcode/doqclient.c index 1a2fd418359b..e6f63a761f35 100644 --- a/testcode/doqclient.c +++ b/testcode/doqclient.c @@ -2699,3 +2699,17 @@ void dtio_mainfdcallback(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), log_assert(0); } #endif + +void fast_reload_service_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(ev), + void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} + +int fast_reload_client_callback(struct comm_point* ATTR_UNUSED(c), + void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), + struct comm_reply* ATTR_UNUSED(repinfo)) +{ + log_assert(0); + return 0; +} diff --git a/testcode/fake_event.c b/testcode/fake_event.c index 2f60b1381e11..f7f3210790eb 100644 --- a/testcode/fake_event.c +++ b/testcode/fake_event.c @@ -938,11 +938,11 @@ listen_create(struct comm_base* base, struct listen_port* ATTR_UNUSED(ports), char* ATTR_UNUSED(http_endpoint), int ATTR_UNUSED(http_notls), struct tcl_list* ATTR_UNUSED(tcp_conn_limit), - void* ATTR_UNUSED(sslctx), struct dt_env* ATTR_UNUSED(dtenv), + void* ATTR_UNUSED(dot_sslctx), void* ATTR_UNUSED(doh_sslctx), + void* ATTR_UNUSED(quic_ssl), + struct dt_env* ATTR_UNUSED(dtenv), struct doq_table* ATTR_UNUSED(table), struct ub_randstate* ATTR_UNUSED(rnd), - const char* ATTR_UNUSED(ssl_service_key), - const char* ATTR_UNUSED(ssl_service_pem), struct config_file* ATTR_UNUSED(cfg), comm_point_callback_type* cb, void *cb_arg) { @@ -1264,7 +1264,7 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet, struct replay_runtime* runtime = (struct replay_runtime*)outnet->base; struct fake_pending* pend = (struct fake_pending*)calloc(1, sizeof(struct fake_pending)); - char z[256]; + char z[LDNS_MAX_DOMAINLEN]; log_assert(pend); log_nametypeclass(VERB_OPS, "pending serviced query", qinfo->qname, qinfo->qtype, qinfo->qclass); @@ -1484,6 +1484,11 @@ size_t comm_point_get_mem(struct comm_point* ATTR_UNUSED(c)) return 0; } +size_t comm_timer_get_mem(struct comm_timer* ATTR_UNUSED(timer)) +{ + return 0; +} + size_t serviced_get_mem(struct serviced_query* ATTR_UNUSED(c)) { return 0; @@ -1939,7 +1944,8 @@ int comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet, } int outnet_get_tcp_fd(struct sockaddr_storage* ATTR_UNUSED(addr), - socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(tcp_mss), int ATTR_UNUSED(dscp)) + socklen_t ATTR_UNUSED(addrlen), int ATTR_UNUSED(tcp_mss), + int ATTR_UNUSED(dscp), int ATTR_UNUSED(nodelay)) { log_assert(0); return -1; @@ -1993,4 +1999,24 @@ void http2_stream_remove_mesh_state(struct http2_stream* ATTR_UNUSED(h2_stream)) { } +void fast_reload_service_cb(int ATTR_UNUSED(fd), short ATTR_UNUSED(event), + void* ATTR_UNUSED(arg)) +{ + log_assert(0); +} + +void fast_reload_thread_stop( + struct fast_reload_thread* ATTR_UNUSED(fast_reload_thread)) +{ + /* nothing */ +} + +int fast_reload_client_callback(struct comm_point* ATTR_UNUSED(c), + void* ATTR_UNUSED(arg), int ATTR_UNUSED(error), + struct comm_reply* ATTR_UNUSED(repinfo)) +{ + log_assert(0); + return 0; +} + /*********** End of Dummy routines ***********/ diff --git a/testcode/testbound.c b/testcode/testbound.c index 442e23434eb4..6da4ceaf2ebf 100644 --- a/testcode/testbound.c +++ b/testcode/testbound.c @@ -601,7 +601,24 @@ void listen_desetup_locks(void) /* nothing */ } +void fast_reload_printq_list_delete( + struct fast_reload_printq* ATTR_UNUSED(list)) +{ + /* nothing */ +} + +void fast_reload_worker_pickup_changes(struct worker* ATTR_UNUSED(worker)) +{ + /* nothing */ +} + #ifdef HAVE_NGTCP2 +void* quic_sslctx_create(char* ATTR_UNUSED(key), char* ATTR_UNUSED(pem), + char* ATTR_UNUSED(verifypem)) +{ + return NULL; +} + void comm_point_doq_callback(int ATTR_UNUSED(fd), short ATTR_UNUSED(event), void* ATTR_UNUSED(arg)) { diff --git a/testcode/unitdname.c b/testcode/unitdname.c index 6769127b9349..08a2dbad774d 100644 --- a/testcode/unitdname.c +++ b/testcode/unitdname.c @@ -39,6 +39,7 @@ */ #include "config.h" +#include <ctype.h> #include "util/log.h" #include "testcode/unitmain.h" #include "util/data/dname.h" @@ -858,6 +859,151 @@ dname_setup_bufs(sldns_buffer* loopbuf, sldns_buffer* boundbuf) sldns_buffer_flip(boundbuf); } +static void +dname_test_str(sldns_buffer* buff) +{ + char result[LDNS_MAX_DOMAINLEN], expect[LDNS_MAX_DOMAINLEN], *e; + size_t i; + unit_show_func("util/data/dname.c", "dname_str"); + + /* root ; expected OK */ + sldns_buffer_clear(buff); + sldns_buffer_write(buff, "\000", 1); + sldns_buffer_flip(buff); + unit_assert( sldns_buffer_limit(buff) == 1 ); + unit_assert( pkt_dname_len(buff) == 1 ); + dname_str(sldns_buffer_begin(buff), result); + unit_assert( strcmp( ".", result) == 0 ); + + /* LDNS_MAX_DOMAINLEN - 1 ; expected OK */ + sldns_buffer_clear(buff); + sldns_buffer_write(buff, + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 64 up to here */ + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 128 up to here */ + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 192 up to here */ + "\074abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567" /* 253 up to here */ + "\000" /* 254 up to here */ + , 254); + sldns_buffer_flip(buff); + unit_assert( sldns_buffer_limit(buff) == 254 ); + unit_assert( pkt_dname_len(buff) == 254 ); + dname_str(sldns_buffer_begin(buff), result); + unit_assert( strcmp( + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567" + ".", result) == 0 ); + + /* LDNS_MAX_DOMAINLEN ; expected OK */ + sldns_buffer_clear(buff); + sldns_buffer_write(buff, + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 64 up to here */ + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 128 up to here */ + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 192 up to here */ + "\075abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678" /* 254 up to here */ + "\000" /* 255 up to here */ + , 255); + sldns_buffer_flip(buff); + unit_assert( sldns_buffer_limit(buff) == 255 ); + unit_assert( pkt_dname_len(buff) == 255 ); + dname_str(sldns_buffer_begin(buff), result); + unit_assert( strcmp( + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ012345678" + ".", result) == 0 ); + + /* LDNS_MAX_DOMAINLEN + 1 ; expected to fail, output uses '&' on the latest label */ + sldns_buffer_clear(buff); + sldns_buffer_write(buff, + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 64 up to here */ + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 128 up to here */ + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 192 up to here */ + "\076abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789" /* 255 up to here */ + "\000" /* 256 up to here */ + , 256); + sldns_buffer_flip(buff); + unit_assert( sldns_buffer_limit(buff) == 256 ); + unit_assert( pkt_dname_len(buff) == 0 ); + dname_str(sldns_buffer_begin(buff), result); + unit_assert( strcmp( + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "&", result) == 0 ); + + /* LDNS_MAX_LABELLEN + 1 ; expected to fail, output uses '#' on the offending label */ + sldns_buffer_clear(buff); + sldns_buffer_write(buff, + "\077abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890" /* 64 up to here */ + "\100abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890a" /* 129 up to here */ + "\000" /* 130 up to here */ + , 130); + sldns_buffer_flip(buff); + unit_assert( sldns_buffer_limit(buff) == 130 ); + unit_assert( pkt_dname_len(buff) == 0 ); + dname_str(sldns_buffer_begin(buff), result); + unit_assert( strcmp( + "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ01234567890." + "#", result) == 0 ); + + /* LDNS_MAX_DOMAINLEN with single labels; expected OK */ + sldns_buffer_clear(buff); + for(i=0; i<=252; i+=2) + sldns_buffer_write(buff, "\001a", 2); + sldns_buffer_write_u8(buff, 0); + sldns_buffer_flip(buff); + unit_assert( sldns_buffer_limit(buff) == 255 ); + unit_assert( pkt_dname_len(buff) == 255 ); + dname_str(sldns_buffer_begin(buff), result); + e = expect; + for(i=0; i<=252; i+=2) { + *e++ = 'a'; + *e++ = '.'; + } + *e = '\0'; + unit_assert( strcmp(expect, result) == 0 ); + + /* LDNS_MAX_DOMAINLEN + 1 with single labels; expected to fail, output uses '&' on the latest label */ + sldns_buffer_clear(buff); + for(i=0; i<=250; i+=2) + sldns_buffer_write(buff, "\001a", 2); + sldns_buffer_write(buff, "\002ab", 3); + sldns_buffer_write_u8(buff, 0); + sldns_buffer_flip(buff); + unit_assert( sldns_buffer_limit(buff) == 256 ); + unit_assert( pkt_dname_len(buff) == 0 ); + dname_str(sldns_buffer_begin(buff), result); + e = expect; + for(i=0; i<=250; i+=2) { + *e++ = 'a'; + *e++ = '.'; + } + *e++ = '&'; + *e = '\0'; + unit_assert( strcmp(expect, result) == 0 ); + + /* Only alphas, numericals and '-', '_' and '*' are allowed in the output */ + for(i=1; i<=255; i++) { + if(isalnum(i) || i == '-' || i == '_' || i == '*') + continue; + sldns_buffer_clear(buff); + sldns_buffer_write_u8(buff, 1); + sldns_buffer_write_u8(buff, (uint8_t)i); + sldns_buffer_write_u8(buff, 0); + sldns_buffer_flip(buff); + unit_assert( sldns_buffer_limit(buff) == 3 ); + unit_assert( pkt_dname_len(buff) == 3); + dname_str(sldns_buffer_begin(buff), result); + if(strcmp( "?.", result) != 0 ) { + log_err("ASCII value '0x%lX' allowed in string output", (unsigned long)i); + unit_assert(0); + } + } +} + void dname_test(void) { sldns_buffer* loopbuf = sldns_buffer_new(14); @@ -884,6 +1030,7 @@ void dname_test(void) dname_test_topdomain(); dname_test_valid(); dname_test_has_label(); + dname_test_str(buff); sldns_buffer_free(buff); sldns_buffer_free(loopbuf); sldns_buffer_free(boundbuf); diff --git a/testcode/unitinfra.c b/testcode/unitinfra.c new file mode 100644 index 000000000000..6834c51eeab8 --- /dev/null +++ b/testcode/unitinfra.c @@ -0,0 +1,209 @@ +/* + * testcode/unitinfra.c - unit test for infra cache. + * + * Copyright (c) 2025, NLnet Labs. All rights reserved. + * + * This software is open source. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * Redistributions of source code must retain the above copyright notice, + * this list of conditions and the following disclaimer. + * + * Redistributions in binary form must reproduce the above copyright notice, + * this list of conditions and the following disclaimer in the documentation + * and/or other materials provided with the distribution. + * + * Neither the name of the NLNET LABS nor the names of its contributors may + * be used to endorse or promote products derived from this software without + * specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED + * TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR + * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + * + */ +/** + * \file + * Tests the infra functionality. + */ + +#include "config.h" +#include "testcode/unitmain.h" +#include "iterator/iterator.h" +#include "services/cache/infra.h" +#include "util/config_file.h" +#include "util/net_help.h" + +/* lookup and get key and data structs easily */ +static struct infra_data* infra_lookup_host(struct infra_cache* infra, + struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, + size_t zonelen, int wr, time_t now, struct infra_key** k) +{ + struct infra_data* d; + struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, + zone, zonelen, wr); + if(!e) return NULL; + d = (struct infra_data*)e->data; + if(d->ttl < now) { + lock_rw_unlock(&e->lock); + return NULL; + } + *k = (struct infra_key*)e->key; + return d; +} + +static void test_keep_probing(struct infra_cache* slab, + struct config_file* cfg, struct sockaddr_storage one, socklen_t onelen, + uint8_t* zone, size_t zonelen, time_t *now, int keep_probing, + int rtt_max_timeout) +{ + uint8_t edns_lame; + int vs, to, lame, dnsseclame, reclame, probedelay; + struct infra_key* k; + struct infra_data* d; + + /* configure */ + cfg->infra_cache_max_rtt = rtt_max_timeout; + config_apply_max_rtt(rtt_max_timeout); + slab->infra_keep_probing = keep_probing; + + /* expired previous entry */ + *now += cfg->host_ttl + 10; + unit_assert( infra_host(slab, &one, onelen, zone, zonelen, + *now, &vs, &edns_lame, &to) ); + + /* simulate timeouts until the USEFUL_SERVER_TOP_TIMEOUT is reached */ + while(to < USEFUL_SERVER_TOP_TIMEOUT) { + unit_assert( infra_rtt_update(slab, &one, onelen, zone, zonelen, + LDNS_RR_TYPE_A, -1, to, *now) ); + unit_assert( infra_host(slab, &one, onelen, zone, zonelen, + *now, &vs, &edns_lame, &to) ); + unit_assert( vs == 0 && to <= USEFUL_SERVER_TOP_TIMEOUT && edns_lame == 0 ); + } + unit_assert( vs == 0 && to == USEFUL_SERVER_TOP_TIMEOUT && edns_lame == 0 ); + + /* don't let the record expire */ + unit_assert( (d=infra_lookup_host(slab, &one, onelen, zone, zonelen, 0, *now, &k)) ); + unit_assert( d->timeout_A >= TIMEOUT_COUNT_MAX ); + unit_assert( d->probedelay > 0 ); + probedelay = d->probedelay; + lock_rw_unlock(&k->entry.lock); + cfg->host_ttl = cfg->host_ttl + *now < probedelay + ?cfg->host_ttl :probedelay + 10; + + /* advance time and check that probing is as expected; we already had a + * lot of A timeouts (checked above). */ + *now = probedelay; + unit_assert( infra_get_lame_rtt(slab, &one, onelen, zone, zonelen, + LDNS_RR_TYPE_A, &lame, &dnsseclame, &reclame, &to, *now) ); + unit_assert( lame == 0 && dnsseclame == 0 && reclame == 0 + && to == keep_probing ?still_useful_timeout() :USEFUL_SERVER_TOP_TIMEOUT); +} + +/** test host cache */ +void infra_test(void) +{ + struct sockaddr_storage one; + socklen_t onelen; + uint8_t* zone = (uint8_t*)"\007example\003com\000"; + size_t zonelen = 13; + struct infra_cache* slab; + struct config_file* cfg = config_create(); + time_t now = 0; + uint8_t edns_lame; + int vs, to; + struct infra_key* k; + struct infra_data* d; + int init = UNKNOWN_SERVER_NICENESS; + int default_max_rtt = USEFUL_SERVER_TOP_TIMEOUT; + + unit_show_feature("infra cache"); + unit_assert(ipstrtoaddr("127.0.0.1", 53, &one, &onelen)); + + slab = infra_create(cfg); + /* insert new record */ + unit_assert( infra_host(slab, &one, onelen, zone, zonelen, now, + &vs, &edns_lame, &to) ); + unit_assert( vs == 0 && to == init && edns_lame == 0 ); + + /* simulate no answer */ + unit_assert( infra_rtt_update(slab, &one, onelen, zone, zonelen, LDNS_RR_TYPE_A, -1, init, now) ); + unit_assert( infra_host(slab, &one, onelen, zone, zonelen, + now, &vs, &edns_lame, &to) ); + unit_assert( vs == 0 && to == init*2 && edns_lame == 0 ); + + /* simulate EDNS lame */ + unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, -1, now) ); + unit_assert( infra_host(slab, &one, onelen, zone, zonelen, + now, &vs, &edns_lame, &to) ); + unit_assert( vs == -1 && to == init*2 && edns_lame == 1); + + /* simulate cache expiry */ + now += cfg->host_ttl + 10; + unit_assert( infra_host(slab, &one, onelen, zone, zonelen, + now, &vs, &edns_lame, &to) ); + unit_assert( vs == 0 && to == init && edns_lame == 0 ); + + /* simulate no lame answer */ + unit_assert( infra_set_lame(slab, &one, onelen, + zone, zonelen, now, 0, 0, LDNS_RR_TYPE_A) ); + unit_assert( (d=infra_lookup_host(slab, &one, onelen, zone, zonelen, 0, now, &k)) ); + unit_assert( d->ttl == now+cfg->host_ttl ); + unit_assert( d->edns_version == 0 ); + unit_assert(!d->isdnsseclame && !d->rec_lame && d->lame_type_A && + !d->lame_other); + lock_rw_unlock(&k->entry.lock); + + /* test merge of data */ + unit_assert( infra_set_lame(slab, &one, onelen, + zone, zonelen, now, 0, 0, LDNS_RR_TYPE_AAAA) ); + unit_assert( (d=infra_lookup_host(slab, &one, onelen, zone, zonelen, 0, now, &k)) ); + unit_assert(!d->isdnsseclame && !d->rec_lame && d->lame_type_A && + d->lame_other); + lock_rw_unlock(&k->entry.lock); + + /* test that noEDNS cannot overwrite known-yesEDNS */ + now += cfg->host_ttl + 10; + unit_assert( infra_host(slab, &one, onelen, zone, zonelen, + now, &vs, &edns_lame, &to) ); + unit_assert( vs == 0 && to == init && edns_lame == 0 ); + + unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, 0, now) ); + unit_assert( infra_host(slab, &one, onelen, zone, zonelen, + now, &vs, &edns_lame, &to) ); + unit_assert( vs == 0 && to == init && edns_lame == 1 ); + + unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, -1, now) ); + unit_assert( infra_host(slab, &one, onelen, zone, zonelen, + now, &vs, &edns_lame, &to) ); + unit_assert( vs == 0 && to == init && edns_lame == 1 ); + + unit_show_feature("infra cache probing (keep-probing off, default infra-cache-max-rtt)"); + test_keep_probing(slab, cfg, one, onelen, zone, zonelen, &now, 0, default_max_rtt); + + unit_show_feature("infra cache probing (keep-probing on, default infra-cache-max-rtt)"); + test_keep_probing(slab, cfg, one, onelen, zone, zonelen, &now, 1, default_max_rtt); + + unit_show_feature("infra cache probing (keep-probing off, low infra-cache-max-rtt)"); + test_keep_probing(slab, cfg, one, onelen, zone, zonelen, &now, 0, 3000); + + unit_show_feature("infra cache probing (keep-probing on, low infra-cache-max-rtt)"); + test_keep_probing(slab, cfg, one, onelen, zone, zonelen, &now, 1, 3000); + + /* Re-apply defaults for other unit tests that follow */ + config_apply_max_rtt(default_max_rtt); + + infra_delete(slab); + config_delete(cfg); +} diff --git a/testcode/unitldns.c b/testcode/unitldns.c index d226ee203c10..f8409fec71b1 100644 --- a/testcode/unitldns.c +++ b/testcode/unitldns.c @@ -172,10 +172,14 @@ rr_test_file(const char* input, const char* check) if(txt_in[0] == 0 || txt_in[0] == '\n' || txt_in[0] == ';') continue; /* read check lines */ - if(!fgets(wire_chk, (int)bufs, chf)) + if(!fgets(wire_chk, (int)bufs, chf)) { printf("%s too short\n", check); - if(!fgets(txt_chk, (int)bufs, chf)) + unit_assert(0); + } + if(!fgets(txt_chk, (int)bufs, chf)) { printf("%s too short\n", check); + unit_assert(0); + } chlineno += 2; if(vbmp) printf("%s:%d %s", check, chlineno-1, wire_chk); if(vbmp) printf("%s:%d %s", check, chlineno, txt_chk); diff --git a/testcode/unitmain.c b/testcode/unitmain.c index 653d3efbe904..334c1af93033 100644 --- a/testcode/unitmain.c +++ b/testcode/unitmain.c @@ -433,103 +433,6 @@ rtt_test(void) unit_assert(UB_STATS_BUCKET_NUM == NUM_BUCKETS_HIST); } -#include "services/cache/infra.h" - -/* lookup and get key and data structs easily */ -static struct infra_data* infra_lookup_host(struct infra_cache* infra, - struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, - size_t zonelen, int wr, time_t now, struct infra_key** k) -{ - struct infra_data* d; - struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen, - zone, zonelen, wr); - if(!e) return NULL; - d = (struct infra_data*)e->data; - if(d->ttl < now) { - lock_rw_unlock(&e->lock); - return NULL; - } - *k = (struct infra_key*)e->key; - return d; -} - -/** test host cache */ -static void -infra_test(void) -{ - struct sockaddr_storage one; - socklen_t onelen; - uint8_t* zone = (uint8_t*)"\007example\003com\000"; - size_t zonelen = 13; - struct infra_cache* slab; - struct config_file* cfg = config_create(); - time_t now = 0; - uint8_t edns_lame; - int vs, to; - struct infra_key* k; - struct infra_data* d; - int init = 376; - - unit_show_feature("infra cache"); - unit_assert(ipstrtoaddr("127.0.0.1", 53, &one, &onelen)); - - slab = infra_create(cfg); - unit_assert( infra_host(slab, &one, onelen, zone, zonelen, now, - &vs, &edns_lame, &to) ); - unit_assert( vs == 0 && to == init && edns_lame == 0 ); - - unit_assert( infra_rtt_update(slab, &one, onelen, zone, zonelen, LDNS_RR_TYPE_A, -1, init, now) ); - unit_assert( infra_host(slab, &one, onelen, zone, zonelen, - now, &vs, &edns_lame, &to) ); - unit_assert( vs == 0 && to == init*2 && edns_lame == 0 ); - - unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, -1, now) ); - unit_assert( infra_host(slab, &one, onelen, zone, zonelen, - now, &vs, &edns_lame, &to) ); - unit_assert( vs == -1 && to == init*2 && edns_lame == 1); - - now += cfg->host_ttl + 10; - unit_assert( infra_host(slab, &one, onelen, zone, zonelen, - now, &vs, &edns_lame, &to) ); - unit_assert( vs == 0 && to == init && edns_lame == 0 ); - - unit_assert( infra_set_lame(slab, &one, onelen, - zone, zonelen, now, 0, 0, LDNS_RR_TYPE_A) ); - unit_assert( (d=infra_lookup_host(slab, &one, onelen, zone, zonelen, 0, now, &k)) ); - unit_assert( d->ttl == now+cfg->host_ttl ); - unit_assert( d->edns_version == 0 ); - unit_assert(!d->isdnsseclame && !d->rec_lame && d->lame_type_A && - !d->lame_other); - lock_rw_unlock(&k->entry.lock); - - /* test merge of data */ - unit_assert( infra_set_lame(slab, &one, onelen, - zone, zonelen, now, 0, 0, LDNS_RR_TYPE_AAAA) ); - unit_assert( (d=infra_lookup_host(slab, &one, onelen, zone, zonelen, 0, now, &k)) ); - unit_assert(!d->isdnsseclame && !d->rec_lame && d->lame_type_A && - d->lame_other); - lock_rw_unlock(&k->entry.lock); - - /* test that noEDNS cannot overwrite known-yesEDNS */ - now += cfg->host_ttl + 10; - unit_assert( infra_host(slab, &one, onelen, zone, zonelen, - now, &vs, &edns_lame, &to) ); - unit_assert( vs == 0 && to == init && edns_lame == 0 ); - - unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, 0, now) ); - unit_assert( infra_host(slab, &one, onelen, zone, zonelen, - now, &vs, &edns_lame, &to) ); - unit_assert( vs == 0 && to == init && edns_lame == 1 ); - - unit_assert( infra_edns_update(slab, &one, onelen, zone, zonelen, -1, now) ); - unit_assert( infra_host(slab, &one, onelen, zone, zonelen, - now, &vs, &edns_lame, &to) ); - unit_assert( vs == 0 && to == init && edns_lame == 1 ); - - infra_delete(slab); - config_delete(cfg); -} - #include "util/edns.h" /* Complete version-invalid client cookie; needs a new one. * Based on edns_cookie_rfc9018_a2 */ diff --git a/testcode/unitmain.h b/testcode/unitmain.h index 99d5240d2217..00b5a6220873 100644 --- a/testcode/unitmain.h +++ b/testcode/unitmain.h @@ -86,5 +86,7 @@ void zonemd_test(void); void tcpreuse_test(void); /** unit test for doq functions */ void doq_test(void); +/** unit test for infra cache functions */ +void infra_test(void); #endif /* TESTCODE_UNITMAIN_H */ diff --git a/testcode/unitneg.c b/testcode/unitneg.c index 59c4e8dcc643..d1d03fc99150 100644 --- a/testcode/unitneg.c +++ b/testcode/unitneg.c @@ -53,7 +53,7 @@ static int negverbose = 0; /** debug printout of neg cache */ static void print_neg_cache(struct val_neg_cache* neg) { - char buf[1024]; + char buf[LDNS_MAX_DOMAINLEN]; struct val_neg_zone* z; struct val_neg_data* d; printf("neg_cache print\n"); diff --git a/testcode/unitverify.c b/testcode/unitverify.c index 275435c73a0d..81c8b13c6d65 100644 --- a/testcode/unitverify.c +++ b/testcode/unitverify.c @@ -425,7 +425,7 @@ nsec3_hash_test_entry(struct entry* e, rbtree_type* ct, { struct query_info qinfo; struct reply_info* rep = NULL; - struct ub_packed_rrset_key* answer, *nsec3; + struct ub_packed_rrset_key* answer, *nsec3, *nsec3_region; struct nsec3_cached_hash* hash = NULL; int ret; uint8_t* qname; @@ -443,7 +443,11 @@ nsec3_hash_test_entry(struct entry* e, rbtree_type* ct, /* check test is OK */ unit_assert(nsec3 && answer && qname); - ret = nsec3_hash_name(ct, region, buf, nsec3, 0, qname, + /* Copy the nsec3 to the region, so it can stay referenced by the + * ct tree entry. The region is freed when the file is done. */ + nsec3_region = packed_rrset_copy_region(nsec3, region, 0); + + ret = nsec3_hash_name(ct, region, buf, nsec3_region, 0, qname, qinfo.qname_len, &hash); if(ret < 1) { printf("Bad nsec3_hash_name retcode %d\n", ret); diff --git a/testcode/unitzonemd.c b/testcode/unitzonemd.c index a8a168e33fe8..63dc13edab33 100644 --- a/testcode/unitzonemd.c +++ b/testcode/unitzonemd.c @@ -111,7 +111,7 @@ static void zonemd_generate_test(const char* zname, char* zfile, digestdup[i] = toupper((unsigned char)digestdup[i]); } if(verbosity >= VERB_ALGO) { - char zname[255+1]; + char zname[LDNS_MAX_DOMAINLEN]; dname_str(z->name, zname); printf("zonemd generated for %s in %s with " "scheme=%d hashalgo=%d\n", zname, z->zonefile, diff --git a/testdata/09-unbound-control.tdir/09-unbound-control.conf b/testdata/09-unbound-control.tdir/09-unbound-control.conf index 719e92309513..be65336eaf5e 100644 --- a/testdata/09-unbound-control.tdir/09-unbound-control.conf +++ b/testdata/09-unbound-control.tdir/09-unbound-control.conf @@ -13,6 +13,7 @@ server: msg-cache-size: 4m rrset-cache-size: 4m minimal-responses: yes + trust-anchor: "always.empty. 3600 IN DS 50602 8 2 FA8EE175C47325F4BD46D8A4083C3EBEB11C977D689069F2B41F1A29 B22446B1" # This is nonsense, just to kick the validator view: name: testview view-first: yes # Allow falling back to global local data diff --git a/testdata/09-unbound-control.tdir/09-unbound-control.test b/testdata/09-unbound-control.tdir/09-unbound-control.test index 8bd2220f3429..da284c2c0ccd 100644 --- a/testdata/09-unbound-control.tdir/09-unbound-control.test +++ b/testdata/09-unbound-control.tdir/09-unbound-control.test @@ -68,9 +68,12 @@ fail_answer () { # Issue an unbound-control command # $@: command arguments -control_command () { +control_command() { echo "$PRE/unbound-control $@" $PRE/unbound-control $@ > outfile + exitstatus=$? + cat outfile + return $exitstatus } # Reload the server and check the reload has finished processing @@ -249,6 +252,25 @@ expect_exit_value 1 teststep "clean reload" clean_reload +# The flush negative only works if the server is either on 1 thread, +# or there is threading enabled. Multiple processes does not work for the +# test, since the printout does not have the stats of a global cache. +if test $num_threads -le 1 -o "$have_threads" = "yes"; then +teststep "Check negative flushing" +query always.empty. +expect_answer "SERVFAIL" +query always.empty. DNSKEY +expect_answer "SERVFAIL" +control_command -c ub.conf flush_negative +expect_exit_value 0 +expect_answer "^ok removed .*, 3 messages and 1 key entries" +control_command -c ub.conf flush_negative +expect_exit_value 0 +expect_answer "^ok removed .*, 0 messages and 0 key entries" +else + echo "> skip Check negative flushing, because no threads" +fi + teststep "create a new local zone" control_command -c ub.conf local_zone example.net static expect_exit_value 0 diff --git a/testdata/09-unbound-control.tdir/09-unbound-control.testns b/testdata/09-unbound-control.tdir/09-unbound-control.testns index 9a5192fabc4f..311af0f7e771 100644 --- a/testdata/09-unbound-control.tdir/09-unbound-control.testns +++ b/testdata/09-unbound-control.tdir/09-unbound-control.testns @@ -1,5 +1,4 @@ ; nameserver test file -$ORIGIN example.com. $TTL 3600 ENTRY_BEGIN @@ -7,9 +6,9 @@ MATCH opcode qtype qname REPLY QR AA NOERROR ADJUST copy_id SECTION QUESTION -www IN A +www.example.com. IN A SECTION ANSWER -www IN A 10.20.30.40 +www.example.com. IN A 10.20.30.40 ENTRY_END ENTRY_BEGIN @@ -19,3 +18,27 @@ ADJUST copy_id SECTION QUESTION www.example.net. IN A ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA NOERROR +ADJUST copy_id +SECTION QUESTION +always.empty. IN A +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA NOERROR +ADJUST copy_id +SECTION QUESTION +always.empty. IN DNSKEY +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA NOERROR +ADJUST copy_id +SECTION QUESTION +_ta-c5aa.always.empty. IN NULL +ENTRY_END diff --git a/testdata/acl_interface.tdir/acl_interface.conf b/testdata/acl_interface.tdir/acl_interface.conf index 1d9f8c9aae09..b1d94857317f 100644 --- a/testdata/acl_interface.tdir/acl_interface.conf +++ b/testdata/acl_interface.tdir/acl_interface.conf @@ -139,6 +139,20 @@ server: interface-view: @INTERFACE@@@PORT_VIEW_EXT@ "ext" interface-view: @INTERFACE@@@PORT_VIEW_INTEXT@ "intext" +# Interface with scope_id + interface: @INTERFACE@vlan50@@PORT_ALLOW@ + interface: @INTERFACE@vlan51@@PORT_ALLOW@ + interface-tag: @INTERFACE@vlan50@@PORT_ALLOW@ "one" + interface-tag: @INTERFACE@vlan51@@PORT_ALLOW@ "two" + interface-action: @INTERFACE@vlan50@@PORT_ALLOW@ allow + interface-action: @INTERFACE@vlan51@@PORT_ALLOW@ allow + local-zone: one.vtest. static + local-data: "one.vtest. A 1.1.1.1" + local-zone-tag: one.vtest. "one" + local-zone: two.vtest. static + local-data: "two.vtest. A 2.2.2.2" + local-zone-tag: two.vtest. "two" + # Local zones configuration local-zone: local. transparent local-data: "local. A 0.0.0.0" diff --git a/testdata/acl_interface.tdir/acl_interface.test.scenario b/testdata/acl_interface.tdir/acl_interface.test.scenario index 4ae0a42f0602..6348d2ef4a1a 100644 --- a/testdata/acl_interface.tdir/acl_interface.test.scenario +++ b/testdata/acl_interface.tdir/acl_interface.test.scenario @@ -17,6 +17,15 @@ ip addr add $INTERFACE_ADDR_3 dev $INTERFACE ip addr add $INTERFACE_ADDR_4 dev $INTERFACE ip link set $INTERFACE up +ip link add ${INTERFACE}vlan50 type dummy +ip addr add fe80::2/64 dev ${INTERFACE}vlan50 +ip link add ${INTERFACE}vlan51 type dummy +ip addr add fe80::2/64 dev ${INTERFACE}vlan51 +ip link set ${INTERFACE}vlan50 up +ip link set ${INTERFACE}vlan51 up + +ip addr show + # start the forwarder in the background get_ldns_testns $LDNS_TESTNS -p $FORWARD_PORT acl_interface.testns >fwd.log 2>&1 & @@ -250,4 +259,10 @@ for addr in $INTERFACE_ADDR_1 $INTERFACE_ADDR_2 $INTERFACE_ADDR_3 $INTERFACE_ADD expect_external_answer done +query_addr fe80::2%${INTERFACE}vlan50 $PORT_ALLOW "one.vtest." +expect_tag_one_answer + +query_addr fe80::2%${INTERFACE}vlan51 $PORT_ALLOW "two.vtest." +expect_tag_two_answer + end 0 diff --git a/testdata/auth_tls.tdir/auth_tls.pre b/testdata/auth_tls.tdir/auth_tls.pre index ebeee24c5658..cf652b1dc541 100644 --- a/testdata/auth_tls.tdir/auth_tls.pre +++ b/testdata/auth_tls.tdir/auth_tls.pre @@ -5,6 +5,7 @@ [ -f .tpkg.var.test ] && source .tpkg.var.test . ../common.sh +#skip_test "Skip test due to no UDP service for SOA query" PRE="../.." if test -n "$NSD"; then : diff --git a/testdata/auth_tls_failcert.tdir/auth_tls_failcert.pre b/testdata/auth_tls_failcert.tdir/auth_tls_failcert.pre index 519c363dbb7a..56da4af739e4 100644 --- a/testdata/auth_tls_failcert.tdir/auth_tls_failcert.pre +++ b/testdata/auth_tls_failcert.tdir/auth_tls_failcert.pre @@ -5,6 +5,7 @@ [ -f .tpkg.var.test ] && source .tpkg.var.test . ../common.sh +#skip_test "Skip test due to no UDP service for SOA query" PRE="../.." if test -n "$NSD"; then : diff --git a/testdata/cachedb_expired.crpl b/testdata/cachedb_expired.crpl index 9f9ff677c6d1..d3bf06fe1a1b 100644 --- a/testdata/cachedb_expired.crpl +++ b/testdata/cachedb_expired.crpl @@ -4,6 +4,7 @@ server: qname-minimisation: no minimal-responses: no serve-expired: yes + serve-expired-client-timeout: 0 module-config: "cachedb iterator" cachedb: diff --git a/testdata/cachedb_expired_reply_ttl.crpl b/testdata/cachedb_expired_reply_ttl.crpl index b5f34050594e..03fd01add476 100644 --- a/testdata/cachedb_expired_reply_ttl.crpl +++ b/testdata/cachedb_expired_reply_ttl.crpl @@ -4,6 +4,7 @@ server: qname-minimisation: no minimal-responses: no serve-expired: yes + serve-expired-client-timeout: 0 serve-expired-reply-ttl: 30 module-config: "cachedb iterator" diff --git a/testdata/cachedb_servfail_cname.crpl b/testdata/cachedb_servfail_cname.crpl index 221f00d4df54..99b3d51f9135 100644 --- a/testdata/cachedb_servfail_cname.crpl +++ b/testdata/cachedb_servfail_cname.crpl @@ -3,7 +3,7 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: no minimal-responses: no - ;serve-expired: yes + serve-expired: no module-config: "cachedb iterator" cachedb: diff --git a/testdata/cachedb_val_expired.crpl b/testdata/cachedb_val_expired.crpl index 4a51e8272379..741445ce8515 100644 --- a/testdata/cachedb_val_expired.crpl +++ b/testdata/cachedb_val_expired.crpl @@ -4,6 +4,7 @@ server: qname-minimisation: no minimal-responses: yes serve-expired: yes + serve-expired-client-timeout: 0 ;module-config: "subnetcache validator cachedb iterator" module-config: "validator cachedb iterator" diff --git a/testdata/common.sh b/testdata/common.sh index bf2d301eb815..48b8204d2c51 100644 --- a/testdata/common.sh +++ b/testdata/common.sh @@ -1,7 +1,8 @@ # common.sh - an include file for commonly used functions for test code. # BSD licensed (see LICENSE file). # -# Version 6 +# Version 7 +# 2025-04-04: speed up kill_pid. # 2023-12-06: list wait_for_soa_serial in overview # 2023-12-06: get_ldns_notify, skip_test and teststep, and previous changes # also included are wait_logfile, cpu_count, process_cpu_list, and @@ -309,6 +310,7 @@ kill_pid () { local WAIT_THRES=30 local try kill $1 + sleep .001 for (( try=0 ; try <= $MAX_DOWN_TRY ; try++ )) ; do if kill -0 $1 >/dev/null 2>&1; then : @@ -322,6 +324,8 @@ kill_pid () { fi if test $try -ge $WAIT_THRES; then sleep 1 + else + sleep .01 fi # re-send the signal kill $1 >/dev/null 2>&1 diff --git a/testdata/dns_error_reporting.rpl b/testdata/dns_error_reporting.rpl new file mode 100644 index 000000000000..f1fac12a2284 --- /dev/null +++ b/testdata/dns_error_reporting.rpl @@ -0,0 +1,200 @@ +; Test DNS Error Reporting. + +server: + module-config: "validator iterator" + trust-anchor-signaling: no + target-fetch-policy: "0 0 0 0 0" + verbosity: 4 + qname-minimisation: no + minimal-responses: no + rrset-roundrobin: no + trust-anchor: "a.domain DS 50602 8 2 FA8EE175C47325F4BD46D8A4083C3EBEB11C977D689069F2B41F1A29B22446B1" + ede: no # It is not needed for dns-error-reporting; only for clients to receive EDEs + dns-error-reporting: yes + do-ip6: no + +stub-zone: + name: domain + stub-addr: 0.0.0.0 +stub-zone: + name: an.agent + stub-addr: 0.0.0.2 +CONFIG_END + +SCENARIO_BEGIN Test DNS Error Reporting + +; domain +RANGE_BEGIN 0 100 + ADDRESS 0.0.0.0 + ENTRY_BEGIN + MATCH opcode qtype qname + ADJUST copy_id + REPLY QR NOERROR + SECTION QUESTION + a.domain. IN A + SECTION AUTHORITY + a.domain. IN NS ns.a.domain. + SECTION ADDITIONAL + ns.a.domain. IN A 0.0.0.1 + HEX_EDNSDATA_BEGIN + 00 12 ; opt-code (Report-Channel) + 00 0A ; opt-len + 02 61 6E 05 61 67 65 6E 74 00 ; an.agent. + HEX_EDNSDATA_END + ENTRY_END +RANGE_END + +; a.domain +RANGE_BEGIN 0 9 + ADDRESS 0.0.0.1 + ENTRY_BEGIN + MATCH opcode qtype qname + ADJUST copy_id + REPLY QR NOERROR + SECTION QUESTION + a.domain. IN DNSKEY + ENTRY_END + ENTRY_BEGIN + MATCH opcode qtype qname + ADJUST copy_id + REPLY QR NOERROR + SECTION QUESTION + a.domain. IN A + SECTION ANSWER + a.domain. 5 IN A 0.0.0.0 + ; No RRSIG to trigger validation error (and EDE) + SECTION ADDITIONAL + ; No Report-Channel here + ENTRY_END +RANGE_END + +; a.domain +RANGE_BEGIN 10 100 + ADDRESS 0.0.0.1 + ENTRY_BEGIN + MATCH opcode qtype qname + ADJUST copy_id + REPLY QR NOERROR + SECTION QUESTION + a.domain. IN DNSKEY + ENTRY_END + ENTRY_BEGIN + MATCH opcode qtype qname + ADJUST copy_id + REPLY QR NOERROR + SECTION QUESTION + a.domain. IN A + SECTION ANSWER + a.domain. 5 IN A 0.0.0.0 + ; No RRSIG to trigger validator error and EDE + SECTION ADDITIONAL + HEX_EDNSDATA_BEGIN + 00 12 ; opt-code (Report-Channel) + 00 0A ; opt-len + 02 61 6E 05 61 67 65 6E 74 00 ; an.agent. + HEX_EDNSDATA_END + ENTRY_END +RANGE_END + +; an.agent +RANGE_BEGIN 10 20 + ADDRESS 0.0.0.2 + ENTRY_BEGIN + MATCH opcode qtype qname + ADJUST copy_id + REPLY QR NOERROR + SECTION QUESTION + _er.1.a.domain.9._er.an.agent. IN TXT + SECTION ANSWER + _er.1.a.domain.9._er.an.agent. IN TXT "OK" + ENTRY_END +RANGE_END + +; Query +STEP 0 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +a.domain. IN A +ENTRY_END + +; Check that validation failed (no DNS error reporting at this state; +; 'domain' did give an error reporting agent, but the latest upstream +; 'a.domain' did not) +STEP 1 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA SERVFAIL +SECTION QUESTION +a.domain. IN A +ENTRY_END + +; Wait for the a.domain query to expire (TTL 5) +STEP 3 TIME_PASSES ELAPSE 6 + +; Query again +STEP 10 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +a.domain. IN A +ENTRY_END + +; Check that validation failed +; (a DNS Error Report query should have been generated) +STEP 11 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA SERVFAIL +SECTION QUESTION +a.domain. IN A +ENTRY_END + +; Check explicitly that the DNS Error Report query is cached. +STEP 20 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +_er.1.a.domain.9._er.an.agent. IN TXT +ENTRY_END + +; At this range there are no configured agents to answer this. +; If the DNS Error Report query is not answered from the cache the test will +; fail with pending messages. +STEP 21 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY RD QR RA NOERROR +SECTION QUESTION +_er.1.a.domain.9._er.an.agent. IN TXT +SECTION ANSWER +_er.1.a.domain.9._er.an.agent. IN TXT "OK" +ENTRY_END + +; Wait for the a.domain query to expire (5 TTL). +; The DNS Error Report query should still be cached (SOA negative). +STEP 30 TIME_PASSES ELAPSE 6 + +; Force a DNS Error Report query generation again. +STEP 31 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +a.domain. IN A +ENTRY_END + +; Check that validation failed +STEP 32 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA SERVFAIL +SECTION QUESTION +a.domain. IN A +ENTRY_END + +; The same DNS Error Report query will be generated as above. +; No agent is configured at this range to answer the DNS Error Report query. +; If the DNS Error Report query is not used from the cache the test will fail +; with pending messages. + +SCENARIO_END diff --git a/testdata/dnstap.tdir/dnstap.conf b/testdata/dnstap.tdir/dnstap.conf index fc382ccfd4e0..b5497bfebe86 100644 --- a/testdata/dnstap.tdir/dnstap.conf +++ b/testdata/dnstap.tdir/dnstap.conf @@ -12,8 +12,9 @@ server: do-not-query-localhost: no local-zone: "example.net." redirect local-data: "example.net. IN A 10.20.30.41" - serve-expired: yes - serve-expired-reply-ttl: 30 + serve-expired: yes + serve-expired-client-timeout: 0 + serve-expired-reply-ttl: 30 remote-control: control-enable: yes control-interface: 127.0.0.1 diff --git a/testdata/fast_reload_fwd.tdir/auth1.zone b/testdata/fast_reload_fwd.tdir/auth1.zone new file mode 100644 index 000000000000..b6b551a42dd5 --- /dev/null +++ b/testdata/fast_reload_fwd.tdir/auth1.zone @@ -0,0 +1,2 @@ +@ SOA ns root 1 3600 300 7200 3600 +www A 1.2.3.4 diff --git a/testdata/fast_reload_fwd.tdir/auth2.zone b/testdata/fast_reload_fwd.tdir/auth2.zone new file mode 100644 index 000000000000..fc59810c9a85 --- /dev/null +++ b/testdata/fast_reload_fwd.tdir/auth2.zone @@ -0,0 +1,2 @@ +@ SOA ns root 1 3600 300 7200 3600 +www A 1.2.3.5 diff --git a/testdata/fast_reload_fwd.tdir/fast_reload_fwd.conf b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.conf new file mode 100644 index 000000000000..dca76342f172 --- /dev/null +++ b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.conf @@ -0,0 +1,107 @@ +server: + verbosity: 4 + num-threads: 1 + interface: 127.0.0.1 + port: @PORT@ + use-syslog: no + directory: "" + pidfile: "unbound.pid" + chroot: "" + username: "" + do-not-query-localhost: no + trust-anchor: "ta1.example.com DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af" + trust-anchor: "ta2.example.com DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af" + trust-anchor: "ta3.example.com DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af" + domain-insecure: "insec1.ta1.example.com" + domain-insecure: "insec2.ta1.example.com" + domain-insecure: "insec3.ta1.example.com" + +forward-zone: + name: "." + forward-addr: "127.0.0.1@12345" + +remote-control: + control-enable: yes + control-interface: @CONTROL_PATH@/controlpipe.@CONTROL_PID@ + control-use-cert: no + +forward-zone: + name: "example1.org" + forward-addr: "127.0.0.1@@NS1_PORT@" + +forward-zone: + name: "example2.org" + forward-addr: "127.0.0.1@@NS1_PORT@" + +forward-zone: + name: "example3.org" + forward-addr: "127.0.0.1@@NS1_PORT@" + +forward-zone: + name: "example4.org" + forward-addr: "127.0.0.1@@NS2_PORT@" + +forward-zone: + name: "example5.org" + forward-addr: "127.0.0.1@@NS2_PORT@" + +forward-zone: + name: "example6.org" + forward-addr: "127.0.0.1@@NS2_PORT@" + +stub-zone: + name: "stub1.org" + stub-addr: "127.0.0.1@@NS1_PORT@" + stub-prime: no + +stub-zone: + name: "stub2.org" + stub-addr: "127.0.0.1@@NS1_PORT@" + stub-prime: no + +stub-zone: + name: "stub3.org" + stub-addr: "127.0.0.1@@NS1_PORT@" + stub-prime: no + +stub-zone: + name: "stub4.org" + stub-addr: "127.0.0.1@@NS2_PORT@" + stub-prime: no + +stub-zone: + name: "stub5.org" + stub-addr: "127.0.0.1@@NS2_PORT@" + stub-prime: no + +stub-zone: + name: "stub6.org" + stub-addr: "127.0.0.1@@NS2_PORT@" + stub-prime: no + +auth-zone: + name: "auth1.org" + zonefile: "auth1.zone" + +auth-zone: + name: "auth2.org" + zonefile: "auth1.zone" + +auth-zone: + name: "auth3.org" + zonefile: "auth1.zone" + +auth-zone: + name: "auth5.org" + zonefile: "auth5.zone" + primary: 127.0.0.1@@NS1_PORT@ + +auth-zone: + name: "auth6.org" + zonefile: "auth6.zone" + primary: 127.0.0.1@@NS1_PORT@ + +auth-zone: + name: "auth7.org" + zonefile: "auth7.zone" + primary: 127.0.0.1@@NS1_PORT@ diff --git a/testdata/fast_reload_fwd.tdir/fast_reload_fwd.conf2 b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.conf2 new file mode 100644 index 000000000000..dbe6e4ffa821 --- /dev/null +++ b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.conf2 @@ -0,0 +1,108 @@ +server: + verbosity: 4 + num-threads: 1 + interface: 127.0.0.1 + port: @PORT@ + use-syslog: no + directory: "" + pidfile: "unbound.pid" + chroot: "" + username: "" + do-not-query-localhost: no + trust-anchor: "ta1.example.com DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af" + trust-anchor: "ta3.example.com DS 55567 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af" + trust-anchor: "ta4.example.com DS 55566 8 2 9c148338951ce1c3b5cd3da532f3d90dfcf92595148022f2c2fd98e5deee90af" + domain-insecure: "insec1.ta1.example.com" + domain-insecure: "insec3.ta1.example.com" + domain-insecure: "insec4.ta1.example.com" + +forward-zone: + name: "." + # No addresses makes the server return SERVFAIL for deleted zones. + #forward-addr: "127.0.0.1@12345" + +remote-control: + control-enable: yes + control-interface: @CONTROL_PATH@/controlpipe.@CONTROL_PID@ + control-use-cert: no + +forward-zone: + name: "example1.org" + forward-addr: "127.0.0.1@@NS2_PORT@" + +forward-zone: + name: "example2.org" + forward-addr: "127.0.0.1@@NS1_PORT@" + +forward-zone: + name: "example3.org" + forward-addr: "127.0.0.1@@NS2_PORT@" + +forward-zone: + name: "example4.org" + forward-addr: "127.0.0.1@@NS1_PORT@" + +forward-zone: + name: "example5.org" + forward-addr: "127.0.0.1@@NS2_PORT@" + +forward-zone: + name: "example6.org" + forward-addr: "127.0.0.1@@NS1_PORT@" + +stub-zone: + name: "stub1.org" + stub-addr: "127.0.0.1@@NS2_PORT@" + stub-prime: no + +stub-zone: + name: "stub2.org" + stub-addr: "127.0.0.1@@NS1_PORT@" + stub-prime: no + +stub-zone: + name: "stub3.org" + stub-addr: "127.0.0.1@@NS2_PORT@" + stub-prime: no + +stub-zone: + name: "stub4.org" + stub-addr: "127.0.0.1@@NS1_PORT@" + stub-prime: no + +stub-zone: + name: "stub5.org" + stub-addr: "127.0.0.1@@NS2_PORT@" + stub-prime: no + +stub-zone: + name: "stub6.org" + stub-addr: "127.0.0.1@@NS1_PORT@" + stub-prime: no + +auth-zone: + name: "auth1.org" + zonefile: "auth1.zone" + +auth-zone: + name: "auth3.org" + zonefile: "auth2.zone" + +auth-zone: + name: "auth4.org" + zonefile: "auth2.zone" + +auth-zone: + name: "auth5.org" + zonefile: "auth5.zone" + primary: 127.0.0.1@@NS1_PORT@ + +auth-zone: + name: "auth7.org" + zonefile: "auth7.zone" + primary: 127.0.0.1@@NS2_PORT@ + +auth-zone: + name: "auth8.org" + zonefile: "auth8.zone" + primary: 127.0.0.1@@NS1_PORT@ diff --git a/testdata/fast_reload_fwd.tdir/fast_reload_fwd.dsc b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.dsc new file mode 100644 index 000000000000..422cdee4660c --- /dev/null +++ b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.dsc @@ -0,0 +1,16 @@ +BaseName: fast_reload_fwd +Version: 1.0 +Description: Test fast reload change of forwards and stubs. +CreationDate: Thu Jan 22 11:55:55 CET 2024 +Maintainer: dr. W.C.A. Wijngaards +Category: +Component: +CmdDepends: +Depends: +Help: +Pre: fast_reload_fwd.pre +Post: fast_reload_fwd.post +Test: fast_reload_fwd.test +AuxFiles: +Passed: +Failure: diff --git a/testdata/fast_reload_fwd.tdir/fast_reload_fwd.ns1 b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.ns1 new file mode 100644 index 000000000000..d9644414b8e7 --- /dev/null +++ b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.ns1 @@ -0,0 +1,339 @@ +; match A records and return a reply indicating it is this server. +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example1.org. IN A +SECTION ANSWER +www.example1.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example2.org. IN A +SECTION ANSWER +www.example2.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example3.org. IN A +SECTION ANSWER +www.example3.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example4.org. IN A +SECTION ANSWER +www.example4.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example5.org. IN A +SECTION ANSWER +www.example5.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example6.org. IN A +SECTION ANSWER +www.example6.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.example1.org. IN A +SECTION ANSWER +www2.example1.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.example2.org. IN A +SECTION ANSWER +www2.example2.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.example3.org. IN A +SECTION ANSWER +www2.example3.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.example4.org. IN A +SECTION ANSWER +www2.example4.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.example5.org. IN A +SECTION ANSWER +www2.example5.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.example6.org. IN A +SECTION ANSWER +www2.example6.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.stub1.org. IN A +SECTION ANSWER +www.stub1.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.stub2.org. IN A +SECTION ANSWER +www.stub2.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.stub3.org. IN A +SECTION ANSWER +www.stub3.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.stub4.org. IN A +SECTION ANSWER +www.stub4.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.stub5.org. IN A +SECTION ANSWER +www.stub5.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.stub6.org. IN A +SECTION ANSWER +www.stub6.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.stub1.org. IN A +SECTION ANSWER +www2.stub1.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.stub2.org. IN A +SECTION ANSWER +www2.stub2.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.stub3.org. IN A +SECTION ANSWER +www2.stub3.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.stub4.org. IN A +SECTION ANSWER +www2.stub4.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.stub5.org. IN A +SECTION ANSWER +www2.stub5.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.stub6.org. IN A +SECTION ANSWER +www2.stub6.org. IN A 1.2.3.1 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +auth5.org. IN SOA +SECTION ANSWER +auth5.org. SOA ns root 1 3600 300 7200 3600 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +auth5.org. IN AXFR +SECTION ANSWER +auth5.org. SOA ns root 1 3600 300 7200 3600 +www.auth5.org. A 1.2.3.4 +auth5.org. SOA ns root 1 3600 300 7200 3600 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +auth6.org. IN SOA +SECTION ANSWER +auth6.org. SOA ns root 1 3600 300 7200 3600 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +auth6.org. IN AXFR +SECTION ANSWER +auth6.org. SOA ns root 1 3600 300 7200 3600 +www.auth6.org. A 1.2.3.4 +auth6.org. SOA ns root 1 3600 300 7200 3600 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +auth7.org. IN SOA +SECTION ANSWER +auth7.org. SOA ns root 1 3600 300 7200 3600 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +auth7.org. IN AXFR +SECTION ANSWER +auth7.org. SOA ns root 1 3600 300 7200 3600 +www.auth7.org. A 1.2.3.4 +auth7.org. SOA ns root 1 3600 300 7200 3600 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +auth8.org. IN SOA +SECTION ANSWER +auth8.org. SOA ns root 1 3600 300 7200 3600 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +auth8.org. IN AXFR +SECTION ANSWER +auth8.org. SOA ns root 1 3600 300 7200 3600 +www.auth8.org. A 1.2.3.4 +auth8.org. SOA ns root 1 3600 300 7200 3600 +ENTRY_END + +; match anything and return a reply +ENTRY_BEGIN +MATCH opcode +ADJUST copy_id copy_query +REPLY QR AA NOERROR +SECTION QUESTION +example.org. IN SOA +SECTION AUTHORITY +example.org. IN SOA ns1.example.org. hostmaster.example.org. 1 3600 900 86400 3600 +ENTRY_END diff --git a/testdata/fast_reload_fwd.tdir/fast_reload_fwd.ns2 b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.ns2 new file mode 100644 index 000000000000..8e7eb60c81e5 --- /dev/null +++ b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.ns2 @@ -0,0 +1,285 @@ +; match A records and return a reply indicating it is this server. +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example1.org. IN A +SECTION ANSWER +www.example1.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example2.org. IN A +SECTION ANSWER +www.example2.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example3.org. IN A +SECTION ANSWER +www.example3.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example4.org. IN A +SECTION ANSWER +www.example4.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example5.org. IN A +SECTION ANSWER +www.example5.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.example6.org. IN A +SECTION ANSWER +www.example6.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.example1.org. IN A +SECTION ANSWER +www2.example1.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.example2.org. IN A +SECTION ANSWER +www2.example2.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.example3.org. IN A +SECTION ANSWER +www2.example3.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.example4.org. IN A +SECTION ANSWER +www2.example4.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.example5.org. IN A +SECTION ANSWER +www2.example5.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.example6.org. IN A +SECTION ANSWER +www2.example6.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.stub1.org. IN A +SECTION ANSWER +www.stub1.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.stub2.org. IN A +SECTION ANSWER +www.stub2.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.stub3.org. IN A +SECTION ANSWER +www.stub3.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.stub4.org. IN A +SECTION ANSWER +www.stub4.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.stub5.org. IN A +SECTION ANSWER +www.stub5.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.stub6.org. IN A +SECTION ANSWER +www.stub6.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.stub1.org. IN A +SECTION ANSWER +www2.stub1.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.stub2.org. IN A +SECTION ANSWER +www2.stub2.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.stub3.org. IN A +SECTION ANSWER +www2.stub3.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.stub4.org. IN A +SECTION ANSWER +www2.stub4.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.stub5.org. IN A +SECTION ANSWER +www2.stub5.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www2.stub6.org. IN A +SECTION ANSWER +www2.stub6.org. IN A 1.2.3.2 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +auth7.org. IN SOA +SECTION ANSWER +auth7.org. SOA ns root 2 3600 300 7200 3600 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +auth7.org. IN AXFR +SECTION ANSWER +auth7.org. SOA ns root 2 3600 300 7200 3600 +www.auth7.org. A 1.2.3.5 +auth7.org. SOA ns root 2 3600 300 7200 3600 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +auth7.org. IN IXFR +SECTION ANSWER +auth7.org. SOA ns root 2 3600 300 7200 3600 +www.auth7.org. A 1.2.3.5 +auth7.org. SOA ns root 2 3600 300 7200 3600 +ENTRY_END + +; match anything and return a reply +ENTRY_BEGIN +MATCH opcode +ADJUST copy_id copy_query +REPLY QR AA NOERROR +SECTION QUESTION +example.org. IN SOA +SECTION AUTHORITY +example.org. IN SOA ns1.example.org. hostmaster.example.org. 1 3600 900 86400 3600 +ENTRY_END diff --git a/testdata/fast_reload_fwd.tdir/fast_reload_fwd.post b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.post new file mode 100644 index 000000000000..969d0080df63 --- /dev/null +++ b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.post @@ -0,0 +1,27 @@ +# #-- fast_reload_fwd.post --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# source the test var file when it's there +[ -f .tpkg.var.test ] && source .tpkg.var.test +# +# do your teardown here +PRE="../.." +. ../common.sh +kill_pid $NS1_PID +kill_pid $NS2_PID +if test -f unbound.pid; then + if kill -0 $UNBOUND_PID >/dev/null 2>&1; then + kill_pid $UNBOUND_PID + fi +fi +rm -f $CONTROL_PATH/controlpipe.$CONTROL_PID +echo +echo "> ns1.log" +cat ns1.log +echo +echo "> ns2.log" +cat ns2.log +echo +echo "> unbound.log" +cat unbound.log +exit 0 diff --git a/testdata/fast_reload_fwd.tdir/fast_reload_fwd.pre b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.pre new file mode 100644 index 000000000000..42e680d8f041 --- /dev/null +++ b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.pre @@ -0,0 +1,56 @@ +# #-- fast_reload_fwd.pre--# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +PRE="../.." +. ../common.sh +# if no threads; exit +if grep -e "define HAVE_PTHREAD 1" -e "define HAVE_SOLARIS_THREADS 1" -e "define HAVE_WINDOWS_THREADS 1" $PRE/config.h; then + echo "have threads" +else + skip_test "no threads" +fi +if grep -e "define ENABLE_LOCK_CHECKS 1" $PRE/config.h; then + get_make + echo "> (cd $PRE ; $MAKE lock-verify)" + (cd $PRE ; $MAKE lock-verify) +fi + +get_random_port 3 +UNBOUND_PORT=$RND_PORT +NS1_PORT=$(($RND_PORT + 1)) +NS2_PORT=$(($RND_PORT + 2)) +echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test +echo "NS1_PORT=$NS1_PORT" >> .tpkg.var.test +echo "NS2_PORT=$NS2_PORT" >> .tpkg.var.test + +# make config files +CONTROL_PATH=/tmp +CONTROL_PID=$$ +sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@NS1_PORT\@/'$NS1_PORT'/' -e 's/@NS2_PORT\@/'$NS2_PORT'/' -e 's?@CONTROL_PATH\@?'$CONTROL_PATH'?' -e 's/@CONTROL_PID@/'$CONTROL_PID'/' < fast_reload_fwd.conf > ub.conf +sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@NS1_PORT\@/'$NS1_PORT'/' -e 's/@NS2_PORT\@/'$NS2_PORT'/' -e 's?@CONTROL_PATH\@?'$CONTROL_PATH'?' -e 's/@CONTROL_PID@/'$CONTROL_PID'/' < fast_reload_fwd.conf2 > ub.conf2 + +# start forwarders +get_ldns_testns +$LDNS_TESTNS -p $NS1_PORT fast_reload_fwd.ns1 >ns1.log 2>&1 & +NS1_PID=$! +echo "NS1_PID=$NS1_PID" >> .tpkg.var.test + +$LDNS_TESTNS -p $NS2_PORT fast_reload_fwd.ns2 >ns2.log 2>&1 & +NS2_PID=$! +echo "NS2_PID=$NS2_PID" >> .tpkg.var.test + +# start unbound in the background +PRE="../.." +$PRE/unbound -d -c ub.conf >unbound.log 2>&1 & +UNBOUND_PID=$! +echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test +echo "CONTROL_PATH=$CONTROL_PATH" >> .tpkg.var.test +echo "CONTROL_PID=$CONTROL_PID" >> .tpkg.var.test + +cat .tpkg.var.test +wait_ldns_testns_up ns1.log +wait_ldns_testns_up ns2.log +wait_unbound_up unbound.log diff --git a/testdata/fast_reload_fwd.tdir/fast_reload_fwd.test b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.test new file mode 100644 index 000000000000..9248593c75b2 --- /dev/null +++ b/testdata/fast_reload_fwd.tdir/fast_reload_fwd.test @@ -0,0 +1,320 @@ +# #-- fast_reload_fwd.test --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +PRE="../.." +. ../common.sh + +echo "> unbound-control status" +$PRE/unbound-control -c ub.conf status +if test $? -ne 0; then + echo "wrong exit value." + exit 1 +else + echo "exit value: OK" +fi + +# test that the forwards and stubs point to the right upstream. +for x in example1.org example2.org example3.org stub1.org stub2.org stub3.org; do + echo "" + echo "dig www.$x [upstream is NS1]" + dig @127.0.0.1 -p $UNBOUND_PORT www.$x A 2>&1 | tee outfile + if grep "1.2.3.1" outfile; then + echo "response OK" + else + echo "www.$x got the wrong answer" + exit 1 + fi +done + +for x in example4.org example5.org example6.org stub4.org stub5.org stub6.org; do + echo "" + echo "dig www.$x [upstream is NS2]" + dig @127.0.0.1 -p $UNBOUND_PORT www.$x A 2>&1 | tee outfile + if grep "1.2.3.2" outfile; then + echo "response OK" + else + echo "www.$x got the wrong answer" + exit 1 + fi +done + +for x in auth1.org auth2.org auth3.org auth5.org auth6.org auth7.org; do + echo "" + echo "dig www.$x [auth is 1.2.3.4]" + dig @127.0.0.1 -p $UNBOUND_PORT www.$x A 2>&1 | tee outfile + if grep "1.2.3.4" outfile; then + echo "response OK" + else + echo "www.$x got the wrong answer" + exit 1 + fi +done + +echo "" +echo "> list_insecure" +$PRE/unbound-control -c ub.conf list_insecure 2>&1 | tee output +if test $? -ne 0; then + echo "wrong exit value." + exit 1 +fi +if grep "insec1.ta1.example.com" output >/dev/null; then :; else + echo "wrong output" + exit 1 +fi +if grep "insec2.ta1.example.com" output >/dev/null; then :; else + echo "wrong output" + exit 1 +fi +if grep "insec3.ta1.example.com" output >/dev/null; then :; else + echo "wrong output" + exit 1 +fi +echo "" +echo "> trustanchor.unbound" +dig @127.0.0.1 -p $UNBOUND_PORT trustanchor.unbound CH TXT 2>&1 | tee outfile +if grep "ta1.example.com. 55566" outfile >/dev/null; then :; else + echo "wrong output ta1" + exit 1 +fi +if grep "ta2.example.com. 55566" outfile >/dev/null; then :; else + echo "wrong output" + exit 1 +fi +if grep "ta3.example.com. 55566" outfile >/dev/null; then :; else + echo "wrong output" + exit 1 +fi + +echo "" +echo "> replace config file ub.conf" +mv ub.conf ub.conf.orig +mv ub.conf2 ub.conf +echo "" +echo "> unbound-control fast_reload" +$PRE/unbound-control -c ub.conf fast_reload +vv 2>&1 | tee output +if test $? -ne 0; then + echo "wrong exit value." + exit 1 +else + echo "exit value: OK" +fi + +# for the previous digs to www.x the cached value should remain the same +# but for new lookups, to www2.x the new upstream should be used. +for x in example1.org example2.org example3.org stub1.org stub2.org stub3.org; do + echo "" + echo "dig www.$x [upstream is NS1]" + dig @127.0.0.1 -p $UNBOUND_PORT www.$x A 2>&1 | tee outfile + if grep "1.2.3.1" outfile; then + echo "response OK" + else + echo "www.$x got the wrong answer" + exit 1 + fi +done + +for x in example4.org example5.org example6.org stub4.org stub5.org stub6.org; do + echo "" + echo "dig www.$x [upstream is NS2]" + dig @127.0.0.1 -p $UNBOUND_PORT www.$x A 2>&1 | tee outfile + if grep "1.2.3.2" outfile; then + echo "response OK" + else + echo "www.$x got the wrong answer" + exit 1 + fi +done + +# new lookups for www2 go to the upstream. +for x in example2.org example4.org example6.org stub2.org stub4.org stub6.org; do + echo "" + echo "dig www2.$x [upstream is NS1]" + dig @127.0.0.1 -p $UNBOUND_PORT www2.$x A 2>&1 | tee outfile + if grep "1.2.3.1" outfile; then + echo "response OK" + else + echo "www2.$x got the wrong answer" + exit 1 + fi +done + +for x in example1.org example3.org example5.org stub1.org stub3.org stub5.org; do + echo "" + echo "dig www2.$x [upstream is NS2]" + dig @127.0.0.1 -p $UNBOUND_PORT www2.$x A 2>&1 | tee outfile + if grep "1.2.3.2" outfile; then + echo "response OK" + else + echo "www2.$x got the wrong answer" + exit 1 + fi +done + +# auth is unchanged, or at ns1. +for x in auth1.org auth5.org auth8.org; do + echo "" + echo "dig www.$x [auth is 1.2.3.4]" + dig @127.0.0.1 -p $UNBOUND_PORT www.$x A 2>&1 | tee outfile + if grep "1.2.3.4" outfile; then + echo "response OK" + else + echo "www.$x got the wrong answer" + exit 1 + fi +done + +# deleted auth +for x in auth2.org auth6.org; do + echo "" + echo "dig www.$x [auth is deleted]" + dig @127.0.0.1 -p $UNBOUND_PORT www.$x A 2>&1 | tee outfile + if grep "SERVFAIL" outfile; then + echo "response OK" + else + echo "www.$x got the wrong answer" + exit 1 + fi +done + +# changed and added auth +for x in auth3.org auth4.org auth7.org; do + echo "" + echo "dig www.$x [auth is 1.2.3.5]" + dig @127.0.0.1 -p $UNBOUND_PORT www.$x A 2>&1 | tee outfile + if grep "1.2.3.5" outfile; then + echo "response OK" + else + echo "www.$x got the wrong answer" + exit 1 + fi +done + +echo "" +echo "> list_insecure" +$PRE/unbound-control -c ub.conf list_insecure 2>&1 | tee output +if test $? -ne 0; then + echo "wrong exit value." + exit 1 +fi +if grep "insec1.ta1.example.com" output >/dev/null; then :; else + echo "wrong output" + exit 1 +fi +if grep "insec2.ta1.example.com" output >/dev/null; then + echo "wrong output" + exit 1 +fi +if grep "insec3.ta1.example.com" output >/dev/null; then :; else + echo "wrong output" + exit 1 +fi +if grep "insec4.ta1.example.com" output >/dev/null; then :; else + echo "wrong output" + exit 1 +fi +echo "" +echo "> trustanchor.unbound" +dig @127.0.0.1 -p $UNBOUND_PORT trustanchor.unbound CH TXT 2>&1 | tee outfile +if grep "ta1.example.com. 55566" outfile >/dev/null; then :; else + echo "wrong output" + exit 1 +fi +if grep "ta2.example.com. 55566" outfile >/dev/null; then + echo "wrong output" + exit 1 +fi +if grep "ta3.example.com. 55566" outfile >/dev/null; then + echo "wrong output" + exit 1 +fi +if grep "ta3.example.com. 55567" outfile >/dev/null; then :; else + echo "wrong output" + exit 1 +fi +if grep "ta4.example.com. 55566" outfile >/dev/null; then :; else + echo "wrong output" + exit 1 +fi + +echo "" +echo "> test change: add tag1 tag2" +cp ub.conf ub.conf.orig2 +echo "server:" >> ub.conf +echo ' define-tag: "tag1 tag2"' >> ub.conf +echo "> unbound-control fast_reload" +$PRE/unbound-control -c ub.conf fast_reload +vv 2>&1 | tee output +if test $? -ne 0; then + echo "wrong exit value." + exit 1 +else + echo "exit value: OK" +fi + +echo "" +echo "> test change: change to tag2 tag3" +cp ub.conf.orig2 ub.conf +echo "server:" >> ub.conf +echo ' define-tag: "tag2 tag3"' >> ub.conf +echo "> unbound-control fast_reload" +$PRE/unbound-control -c ub.conf fast_reload +vv 2>&1 | tee output +if test $? -ne 0; then + echo "wrong exit value." + exit 1 +else + echo "exit value: OK" +fi +if grep "tags have changed" output; then + echo "output OK" +else + echo "wrong output" + exit 1 +fi + +echo "" +echo "> test change: change cache size" +cp ub.conf.orig2 ub.conf +echo "server:" >> ub.conf +echo " msg-cache-size: 10m" >> ub.conf +echo " rrset-cache-size: 5m" >> ub.conf +echo "> unbound-control fast_reload" +$PRE/unbound-control -c ub.conf fast_reload +vv 2>&1 | tee output +if test $? -ne 0; then + echo "wrong exit value." + exit 1 +else + echo "exit value: OK" +fi + +echo "" +echo "> test change: change nothing, +p too" +$PRE/unbound-control -c ub.conf fast_reload +vv +p 2>&1 | tee output +if test $? -ne 0; then + echo "wrong exit value." + exit 1 +else + echo "exit value: OK" +fi + +echo "" +echo "> stop unbound" +kill_pid $UNBOUND_PID +if test -f unbound.pid; then sleep 1; fi +if test -f unbound.pid; then sleep 1; fi +if test -f unbound.pid; then sleep 1; fi +if test -f unbound.pid; then echo "unbound.pid still there"; fi +# check the locks. +function locktest() { + if test -x $PRE/lock-verify -a -f ublocktrace.0; then + $PRE/lock-verify ublocktrace.* + if test $? -ne 0; then + echo "lock-verify error" + exit 1 + fi + fi +} +locktest + +exit 0 diff --git a/testdata/fast_reload_most_options.tdir/auth.nlnetlabs.nl.zone b/testdata/fast_reload_most_options.tdir/auth.nlnetlabs.nl.zone new file mode 100644 index 000000000000..55b8d34a9e4e --- /dev/null +++ b/testdata/fast_reload_most_options.tdir/auth.nlnetlabs.nl.zone @@ -0,0 +1,3 @@ +$ORIGIN auth.nlnetlabs.nl. +$TTL 60 +@ IN SOA a b 1 2 3 4 5 diff --git a/testdata/fast_reload_most_options.tdir/fast_reload_most_options.conf b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.conf new file mode 100644 index 000000000000..eda3d6763a41 --- /dev/null +++ b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.conf @@ -0,0 +1,143 @@ +# Try to define values for options that don't have "default" options that would +# trigger fast-reload functionality. +server: + verbosity: 4 + num-threads: 4 + interface: 127.0.0.1 + interface: lo + port: @PORT@ + interface-action: lo allow + use-syslog: no + directory: "" + pidfile: "unbound.pid" + chroot: "" + username: "" + do-not-query-localhost: no + + module-config: "respip validator iterator" + + outgoing-interface: 127.0.0.1 + outgoing-port-avoid: "3200-3208" + + define-tag: "tag1 tag2 tag3" + + do-nat64: yes + nat64-prefix: 64:ff9b::0/96 + dns64-prefix: 64:ff9b::0/96 + dns64-ignore-aaaa: "ignore-aaaa.nlnetlabs.nl" + + edns-tcp-keepalive: yes + + response-ip: 192.0.2.0 always_refuse + access-control: 127.0.0.0/8 allow + access-control: ::1 allow + access-control-tag: 192.0.2.0/24 "tag2 tag3" + interface-tag: lo "tag2 tag3" + access-control-tag-action: 192.0.2.0/24 tag3 always_refuse + interface-tag-action: lo tag3 always_refuse + access-control-tag-data: 192.0.2.0/24 tag2 "A 127.0.0.1" + interface-tag-data: lo tag2 "A 127.0.0.1" + access-control-view: 192.0.2.0/24 viewname + interface-view: lo viewname + + nsid: "ascii_something" + + http-user-agent: "httpuseragent" + + caps-exempt: "nlnetlabs.nl" + + private-address: 10.0.0.0/8 + private-address: 172.16.0.0/12 + private-address: 192.168.0.0/16 + private-address: 169.254.0.0/16 + private-address: fd00::/8 + private-address: fe80::/10 + private-address: ::ffff:0:0/96 + + private-domain: "nlnetlabs.nl" + + unwanted-reply-threshold: 10000000 + + do-not-query-address: 1.1.1.1 + do-not-query-address: 8.8.8.8 + do-not-query-address: 9.9.9.9 + + do-not-query-localhost: no + + trust-anchor: "jelte.nlnetlabs.nl. DS 42860 5 1 14D739EB566D2B1A5E216A0BA4D17FA9B038BE4A" + + domain-insecure: "nlnetlabs.nl" + + serve-expired: yes + serve-expired-client-timeout: 1800 + + val-log-level: 2 + + local-zone: refuse.nlnetlabs.nl. refuse + local-zone: override.nlnetlabs.nl. deny + local-zone: tag.nlnetlabs.nl. transparent + local-data: "data.nlnetlabs.nl. TXT localdata" + local-data-ptr: "192.0.2.3 reverse.nlnetlabs.nl." + local-zone-tag: "tag.nlnetlabs.nl" "tag2 tag3" + local-zone-override: "override.nlnetlabs.nl" 192.0.2.0/24 refuse + + + ratelimit: 100 + ratelimit-below-domain: ratelimit.nlnetlabs.nl 1000 + ip-ratelimit: 100 + + tcp-connection-limit: 192.0.2.0/24 12 + + answer-cookie: yes + cookie-secret: "000102030405060708090a0b0c0d0e0f" + + ede: yes + ede-serve-expired: yes + +remote-control: + control-enable: yes + control-interface: @CONTROL_PATH@/controlpipe.@CONTROL_PID@ + control-use-cert: no + +stub-zone: + name: "stub.nlnetlabs.nl" + stub-addr: 192.0.2.68 + stub-prime: no + stub-first: no + stub-tcp-upstream: no + stub-tls-upstream: no + stub-no-cache: no + +forward-zone: + name: "forward.nlnetlabs.nl" + forward-addr: 192.0.2.68 + forward-first: no + forward-tcp-upstream: no + forward-tls-upstream: no + forward-no-cache: no + +auth-zone: + name: "auth.nlnetlabs.nl" + for-downstream: yes + for-upstream: yes + zonemd-check: no + zonemd-reject-absence: no + zonefile: "auth.nlnetlabs.nl.zone" + +view: + name: "viewname" + local-zone: "view.nlnetlabs.nl" redirect + local-data: "view.nlnetlabs.nl A 192.0.2.3" + local-data-ptr: "192.0.2.3 view.nlnetlabs.nl" + view-first: no + +rpz: + name: "rpz.nlnetlabs.nl" + zonefile: "rpz.nlnetlabs.nl.zone" + rpz-action-override: cname + rpz-cname-override: www.example.org + rpz-log: yes + rpz-log-name: "example policy" + rpz-signal-nxdomain-ra: no + for-downstream: no + tags: "tag3" diff --git a/testdata/fast_reload_most_options.tdir/fast_reload_most_options.dsc b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.dsc new file mode 100644 index 000000000000..e0e8e9fd206e --- /dev/null +++ b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.dsc @@ -0,0 +1,16 @@ +BaseName: fast_reload_most_options +Version: 1.0 +Description: Test fast reload on high verbosity with most options. +CreationDate: Fri 28 Feb 2025 15:55:15 CET +Maintainer: Yorgos Thessalonikefs +Category: +Component: +CmdDepends: +Depends: +Help: +Pre: fast_reload_most_options.pre +Post: fast_reload_most_options.post +Test: fast_reload_most_options.test +AuxFiles: +Passed: +Failure: diff --git a/testdata/fast_reload_most_options.tdir/fast_reload_most_options.post b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.post new file mode 100644 index 000000000000..7fd25e3648d0 --- /dev/null +++ b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.post @@ -0,0 +1,11 @@ +# #-- fast_reload_most_options.post --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# source the test var file when it's there +[ -f .tpkg.var.test ] && source .tpkg.var.test +# +# do your teardown here +. ../common.sh +kill_pid $UNBOUND_PID +rm -f $CONTROL_PATH/controlpipe.$CONTROL_PID +cat unbound.log diff --git a/testdata/fast_reload_most_options.tdir/fast_reload_most_options.pre b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.pre new file mode 100644 index 000000000000..47e3642c65c4 --- /dev/null +++ b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.pre @@ -0,0 +1,33 @@ +# #-- fast_reload_most_options.pre--# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +PRE="../.." +. ../common.sh +# if no threads; exit +if grep -e "define HAVE_PTHREAD 1" -e "define HAVE_SOLARIS_THREADS 1" -e "define HAVE_WINDOWS_THREADS 1" $PRE/config.h; then + echo "have threads" +else + skip_test "no threads" +fi + +get_random_port 1 +UNBOUND_PORT=$RND_PORT +echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test + +# make config file +CONTROL_PATH=/tmp +CONTROL_PID=$$ +sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's?@CONTROL_PATH\@?'$CONTROL_PATH'?' -e 's/@CONTROL_PID@/'$CONTROL_PID'/' < fast_reload_most_options.conf > ub.conf +# start unbound in the background +PRE="../.." +$PRE/unbound -d -c ub.conf >unbound.log 2>&1 & +UNBOUND_PID=$! +echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test +echo "CONTROL_PATH=$CONTROL_PATH" >> .tpkg.var.test +echo "CONTROL_PID=$CONTROL_PID" >> .tpkg.var.test + +cat .tpkg.var.test +wait_unbound_up unbound.log diff --git a/testdata/fast_reload_most_options.tdir/fast_reload_most_options.test b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.test new file mode 100644 index 000000000000..20799986071a --- /dev/null +++ b/testdata/fast_reload_most_options.tdir/fast_reload_most_options.test @@ -0,0 +1,42 @@ +# #-- fast_reload_most_options.test --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +PRE="../.." +. ../common.sh + +echo "> unbound-control status" +$PRE/unbound-control -c ub.conf status +if test $? -ne 0; then + echo "wrong exit value." + exit 1 +else + echo "exit value: OK" +fi + +for i in {1..10} +do + + echo "> unbound-control fast_reload +vvdp ($i)" + $PRE/unbound-control -c ub.conf fast_reload +vvdp 2>&1 | tee output + if test $? -ne 0; then + echo "wrong exit value." + exit 1 + else + echo "exit value: OK" + fi + wait_logfile unbound.log "start fast reload thread" 60 + wait_logfile unbound.log "stop fast reload thread" 60 + wait_logfile unbound.log "joined with fastreload thread" 60 + + if grep "ok" output; then + echo "OK" + else + echo "output not correct" + exit 1 + fi +done + +exit 0 diff --git a/testdata/fast_reload_most_options.tdir/rpz.nlnetlabs.nl.zone b/testdata/fast_reload_most_options.tdir/rpz.nlnetlabs.nl.zone new file mode 100644 index 000000000000..71b37150692e --- /dev/null +++ b/testdata/fast_reload_most_options.tdir/rpz.nlnetlabs.nl.zone @@ -0,0 +1,5 @@ +$ORIGIN rpz.nlnetlabs.nl. +$TTL 60 +@ IN SOA a b 1 2 3 4 5 +nxdomain.nlnetlabs.nl IN CNAME . +rpzdata.nlnetlabs.nl IN A 0.0.0.0 diff --git a/testdata/fast_reload_thread.tdir/fast_reload_thread.conf b/testdata/fast_reload_thread.tdir/fast_reload_thread.conf new file mode 100644 index 000000000000..719f4a00eaab --- /dev/null +++ b/testdata/fast_reload_thread.tdir/fast_reload_thread.conf @@ -0,0 +1,20 @@ +server: + verbosity: 4 + num-threads: 1 + interface: 127.0.0.1 + port: @PORT@ + use-syslog: no + directory: "" + pidfile: "unbound.pid" + chroot: "" + username: "" + do-not-query-localhost: no + +forward-zone: + name: "." + forward-addr: "127.0.0.1@12345" + +remote-control: + control-enable: yes + control-interface: @CONTROL_PATH@/controlpipe.@CONTROL_PID@ + control-use-cert: no diff --git a/testdata/fast_reload_thread.tdir/fast_reload_thread.dsc b/testdata/fast_reload_thread.tdir/fast_reload_thread.dsc new file mode 100644 index 000000000000..ec3437b695c0 --- /dev/null +++ b/testdata/fast_reload_thread.tdir/fast_reload_thread.dsc @@ -0,0 +1,16 @@ +BaseName: fast_reload_thread +Version: 1.0 +Description: Test fast reload thread output. +CreationDate: Thu Jan 4 09:25:55 CET 2024 +Maintainer: dr. W.C.A. Wijngaards +Category: +Component: +CmdDepends: +Depends: +Help: +Pre: fast_reload_thread.pre +Post: fast_reload_thread.post +Test: fast_reload_thread.test +AuxFiles: +Passed: +Failure: diff --git a/testdata/fast_reload_thread.tdir/fast_reload_thread.post b/testdata/fast_reload_thread.tdir/fast_reload_thread.post new file mode 100644 index 000000000000..569a17f852ba --- /dev/null +++ b/testdata/fast_reload_thread.tdir/fast_reload_thread.post @@ -0,0 +1,11 @@ +# #-- fast_reload_thread.post --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# source the test var file when it's there +[ -f .tpkg.var.test ] && source .tpkg.var.test +# +# do your teardown here +. ../common.sh +kill_pid $UNBOUND_PID +rm -f $CONTROL_PATH/controlpipe.$CONTROL_PID +cat unbound.log diff --git a/testdata/fast_reload_thread.tdir/fast_reload_thread.pre b/testdata/fast_reload_thread.tdir/fast_reload_thread.pre new file mode 100644 index 000000000000..5521742fa318 --- /dev/null +++ b/testdata/fast_reload_thread.tdir/fast_reload_thread.pre @@ -0,0 +1,34 @@ +# #-- fast_reload_thread.pre--# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +PRE="../.." +. ../common.sh +# if no threads; exit +if grep -e "define HAVE_PTHREAD 1" -e "define HAVE_SOLARIS_THREADS 1" -e "define HAVE_WINDOWS_THREADS 1" $PRE/config.h; then + echo "have threads" +else + skip_test "no threads" +fi + +get_random_port 1 +UNBOUND_PORT=$RND_PORT +echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test + +# make config file +CONTROL_PATH=/tmp +CONTROL_PID=$$ +sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's?@CONTROL_PATH\@?'$CONTROL_PATH'?' -e 's/@CONTROL_PID@/'$CONTROL_PID'/' < fast_reload_thread.conf > ub.conf +# start unbound in the background +PRE="../.." +$PRE/unbound -d -c ub.conf >unbound.log 2>&1 & +UNBOUND_PID=$! +echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test +echo "CONTROL_PATH=$CONTROL_PATH" >> .tpkg.var.test +echo "CONTROL_PID=$CONTROL_PID" >> .tpkg.var.test + +cat .tpkg.var.test +wait_unbound_up unbound.log + diff --git a/testdata/fast_reload_thread.tdir/fast_reload_thread.test b/testdata/fast_reload_thread.tdir/fast_reload_thread.test new file mode 100644 index 000000000000..d2ef258802f7 --- /dev/null +++ b/testdata/fast_reload_thread.tdir/fast_reload_thread.test @@ -0,0 +1,38 @@ +# #-- fast_reload_thread.test --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +PRE="../.." +. ../common.sh + +echo "> unbound-control status" +$PRE/unbound-control -c ub.conf status +if test $? -ne 0; then + echo "wrong exit value." + exit 1 +else + echo "exit value: OK" +fi + +echo "> unbound-control fast_reload" +$PRE/unbound-control -c ub.conf fast_reload 2>&1 | tee output +if test $? -ne 0; then + echo "wrong exit value." + exit 1 +else + echo "exit value: OK" +fi +wait_logfile unbound.log "start fast reload thread" 60 +wait_logfile unbound.log "stop fast reload thread" 60 +wait_logfile unbound.log "joined with fastreload thread" 60 + +if grep "ok" output; then + echo "OK" +else + echo "output not correct" + exit 1 +fi + +exit 0 diff --git a/testdata/fwd_0ttlservfail.rpl b/testdata/fwd_0ttlservfail.rpl index ed912c73bf2f..d50d386d4137 100644 --- a/testdata/fwd_0ttlservfail.rpl +++ b/testdata/fwd_0ttlservfail.rpl @@ -2,6 +2,7 @@ ; config options go here. server: serve-expired: yes + serve-expired-client-timeout: 0 prefetch: yes forward-zone: name: "." forward-addr: 216.0.0.1 CONFIG_END diff --git a/testdata/iter_failreply.rpl b/testdata/iter_failreply.rpl index 393714196d89..e8ad4dd26e31 100644 --- a/testdata/iter_failreply.rpl +++ b/testdata/iter_failreply.rpl @@ -3,7 +3,6 @@ server: target-fetch-policy: "0 0 0 0 0" qname-minimisation: "no" minimal-responses: no - log-servfail: yes stub-zone: name: "." diff --git a/testdata/iter_fwdstubauth.rpl b/testdata/iter_fwdstubauth.rpl new file mode 100644 index 000000000000..fefb6369c864 --- /dev/null +++ b/testdata/iter_fwdstubauth.rpl @@ -0,0 +1,155 @@ +; config options +server: + target-fetch-policy: "0 0 0 0 0" + +auth-zone: + name: "example.tld." + for-upstream: yes + for-downstream: no + fallback-enabled: no + ## this line generates zonefile: "/tmp/xxx.example.tld" + zonefile: +TEMPFILE_NAME example.tld + ## this is the inline file /tmp/xxx.example.tld + ## the tempfiles are deleted when the testrun is over. +TEMPFILE_CONTENTS example.tld +$ORIGIN tld. +example 3600 IN SOA a b 1 2 3 4 5 + 3600 IN NS ns.example.tld. +$ORIGIN example.tld. +ns 3600 IN A 1.2.3.4 +www 3600 IN A 3.3.3.3 +more 3600 IN NS ns.more.tld. +TEMPFILE_END + +forward-zone: + name: "." + forward-addr: 9.9.9.9 + +stub-zone: + name: "tld" + stub-addr: 2.3.4.5 +stub-zone: + name: "more.example.tld" + stub-addr: 2.3.4.7 +CONFIG_END + +SCENARIO_BEGIN Test iterator's ability to route the request to the correct, configured delegation point +; Preference should be auth-zone > stub-zone > forward-zone +; But configuration-wise, since everything is an entry on the forwards tree +; (or a hole in the case of stub/auth), forwards cannot be replaced by +; stubs/auth. +; Also stub/auth zones end the part of the tree that gets forwarded, e.g., +; delegations from an auth/stub cannot be caught by a higher forwarder, it will +; be recursively resolved instead. + +; '.' forwarder +RANGE_BEGIN 0 100 + ADDRESS 9.9.9.9 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +www.deleg.tld. IN A +SECTION ANSWER +www.deleg.tld. IN A 3.3.3.3 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR NOERROR +SECTION QUESTION +www.more.example.tld. IN A +SECTION ANSWER +www.more.example.tld. IN A 3.3.3.3 +ENTRY_END +RANGE_END + +; 'tld.' stub server +RANGE_BEGIN 0 100 + ADDRESS 2.3.4.5 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.tld. IN A +SECTION ANSWER +www.tld. IN A 3.3.3.3 +ENTRY_END +RANGE_END + +; 'more.example.tld.' stub server +RANGE_BEGIN 0 100 + ADDRESS 2.3.4.7 +ENTRY_BEGIN +MATCH opcode qtype qname +ADJUST copy_id +REPLY QR AA NOERROR +SECTION QUESTION +www.more.example.tld. IN A +SECTION ANSWER +www.more.example.tld. IN A 3.3.3.3 +ENTRY_END +RANGE_END + +; query www.tld ... +STEP 1 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +www.tld. IN A +ENTRY_END + +; ... answer should come from 'tld.' stub zone +STEP 2 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA NOERROR +SECTION QUESTION +www.tld. IN A +SECTION ANSWER +www.tld. IN A 3.3.3.3 +ENTRY_END + +; query www.example.tld ... +STEP 3 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +www.example.tld. IN A +ENTRY_END + +; ... answer should come from 'example.tld.' auth zone +STEP 4 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA NOERROR +SECTION QUESTION +www.example.tld. IN A +SECTION ANSWER +www.example.tld. IN A 3.3.3.3 +ENTRY_END + +; query www.more.example.tld ... +STEP 5 QUERY +ENTRY_BEGIN +REPLY RD +SECTION QUESTION +www.more.example.tld. IN A +ENTRY_END + +; ... answer should come from 'more.example.tld.' stub zone +STEP 6 CHECK_ANSWER +ENTRY_BEGIN +MATCH all +REPLY QR RD RA NOERROR +SECTION QUESTION +www.more.example.tld. IN A +SECTION ANSWER +www.more.example.tld. IN A 3.3.3.3 +ENTRY_END + +SCENARIO_END diff --git a/testdata/iter_scrub_rr_length.rpl b/testdata/iter_scrub_rr_length.rpl index 2ef73c2fe152..ee7579f9c246 100644 --- a/testdata/iter_scrub_rr_length.rpl +++ b/testdata/iter_scrub_rr_length.rpl @@ -5,7 +5,6 @@ server: minimal-responses: no rrset-roundrobin: no ede: yes - log-servfail: yes stub-zone: name: "." diff --git a/testdata/log_servfail.tdir/log_servfail.conf b/testdata/log_servfail.tdir/log_servfail.conf new file mode 100644 index 000000000000..2d7c34e68c84 --- /dev/null +++ b/testdata/log_servfail.tdir/log_servfail.conf @@ -0,0 +1,27 @@ +server: + verbosity: 0 + use-syslog: no + directory: "" + pidfile: "unbound.pid" + chroot: "" + username: "" + do-not-query-localhost: no + use-caps-for-id: no + port: @SERVER_PORT@ + interface: 127.0.0.1 + outbound-msg-retry: 0 + + log-servfail: yes + +forward-zone: + name: "a.servfail" + forward-addr: 127.0.0.1@@SERVER_PORT@ + +forward-zone: + name: "b.servfail" + forward-addr: 127.0.0.1@@SERVER_PORT@ + +remote-control: + control-enable: yes + control-port: @CONTROL_PORT@ + control-use-cert: no diff --git a/testdata/log_servfail.tdir/log_servfail.dsc b/testdata/log_servfail.tdir/log_servfail.dsc new file mode 100644 index 000000000000..cf4f455aadf4 --- /dev/null +++ b/testdata/log_servfail.tdir/log_servfail.dsc @@ -0,0 +1,16 @@ +BaseName: log_servfail +Version: 1.0 +Description: Check the log_servfail option +CreationDate: Fri 29 Nov 11:00:00 CEST 2024 +Maintainer: +Category: +Component: +CmdDepends: +Depends: +Help: +Pre: log_servfail.pre +Post: log_servfail.post +Test: log_servfail.test +AuxFiles: +Passed: +Failure: diff --git a/testdata/log_servfail.tdir/log_servfail.post b/testdata/log_servfail.tdir/log_servfail.post new file mode 100644 index 000000000000..a7bd0e88f4bb --- /dev/null +++ b/testdata/log_servfail.tdir/log_servfail.post @@ -0,0 +1,10 @@ +# #-- log_servfail.post --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# source the test var file when it's there +[ -f .tpkg.var.test ] && source .tpkg.var.test +# +# do your teardown here +. ../common.sh +kill_from_pidfile "unbound.pid" +cat unbound.log diff --git a/testdata/log_servfail.tdir/log_servfail.pre b/testdata/log_servfail.tdir/log_servfail.pre new file mode 100644 index 000000000000..54059480824d --- /dev/null +++ b/testdata/log_servfail.tdir/log_servfail.pre @@ -0,0 +1,21 @@ +# #-- log_servfail.pre--# +PRE="../.." +. ../common.sh + +get_random_port 2 +SERVER_PORT=$RND_PORT +CONTROL_PORT=$(($RND_PORT + 1)) +echo "SERVER_PORT=$SERVER_PORT" >> .tpkg.var.test +echo "CONTROL_PORT=$CONTROL_PORT" >> .tpkg.var.test + +# make config file +sed \ + -e 's/@SERVER_PORT\@/'$SERVER_PORT'/' \ + -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' \ + < log_servfail.conf > ub.conf + +# start unbound in the background +$PRE/unbound -d -c ub.conf > unbound.log 2>&1 & + +cat .tpkg.var.test +wait_unbound_up unbound.log diff --git a/testdata/log_servfail.tdir/log_servfail.test b/testdata/log_servfail.tdir/log_servfail.test new file mode 100644 index 000000000000..1d19e5ca3b22 --- /dev/null +++ b/testdata/log_servfail.tdir/log_servfail.test @@ -0,0 +1,47 @@ +# #-- log_servfail.test --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test +PRE="../.." +. ../common.sh + +outfile=dig.out + +teststep "Check if log-servfail logs to output for iterator error" +dig a.servfail @127.0.0.1 -p $SERVER_PORT > $outfile +if ! grep "SERVFAIL" $outfile +then + cat $outfile + echo "Did not get a SERVFAIL response" + exit 1 +fi +if ! grep "SERVFAIL <a\.servfail\. " unbound.log +then + echo "No log-servfail in output" + exit 1 +fi + +teststep "Enable serve expired" +$PRE/unbound-control -c ub.conf set_option serve-expired: yes +if test $? -ne 0 +then + echo "unbound-control command exited with non-zero error code" + exit 1 +fi + +teststep "Check if log-servfail logs to output for iterator error (with serve-expired)" +dig b.servfail @127.0.0.1 -p $SERVER_PORT > $outfile +if ! grep "SERVFAIL" $outfile +then + cat $outfile + echo "Did not get a SERVFAIL response" + exit 1 +fi +if ! grep "SERVFAIL <b\.servfail\. " unbound.log +then + echo "No log-servfail in output" + exit 1 +fi + +exit 0 diff --git a/testdata/redis_replica.tdir/after.zone b/testdata/redis_replica.tdir/after.zone new file mode 100644 index 000000000000..11c268f81497 --- /dev/null +++ b/testdata/redis_replica.tdir/after.zone @@ -0,0 +1,2 @@ +redis.com. IN SOA server. ma.il 1 2 3 4 5 +redis.com. IN A 2.2.2.2 diff --git a/testdata/redis_replica.tdir/before.zone b/testdata/redis_replica.tdir/before.zone new file mode 100644 index 000000000000..8e50c6267516 --- /dev/null +++ b/testdata/redis_replica.tdir/before.zone @@ -0,0 +1,2 @@ +redis.com. IN SOA server. ma.il 1 2 3 4 5 +redis.com. IN A 1.1.1.1 diff --git a/testdata/redis_replica.tdir/redis.conf b/testdata/redis_replica.tdir/redis.conf new file mode 100644 index 000000000000..3b80736e2438 --- /dev/null +++ b/testdata/redis_replica.tdir/redis.conf @@ -0,0 +1,583 @@ +### +### Settings for this test ################################################### +### + +# Accept connections on the specified port, default is 6379 (IANA #815344). +# If port 0 is specified Redis will not listen on a TCP socket. +port 0 + +# Unix socket. +# +# Specify the path for the Unix socket that will be used to listen for +# incoming connections. There is no default, so Redis will not listen +# on a unix socket when not specified. +# +unixsocket @SOCKET@ +# unixsocketperm 700 + +# By default Redis does not run as a daemon. Use 'yes' if you need it. +# Note that Redis will write a pid file in /var/run/redis.pid when daemonized. +# When Redis is supervised by upstart or systemd, this parameter has no impact. +daemonize no + +# Specify the server verbosity level. +# This can be one of: +# debug (a lot of information, useful for development/testing) +# verbose (many rarely useful info, but not a mess like the debug level) +# notice (moderately verbose, what you want in production probably) +# warning (only very important / critical messages are logged) +# nothing (nothing is logged) +loglevel notice + +# Specify the log file name. Also the empty string can be used to force +# Redis to log on the standard output. Note that if you use standard +# output for logging but daemonize, logs will be sent to /dev/null +logfile @LOGFILE@ + +# To enable logging to the system logger, just set 'syslog-enabled' to yes, +# and optionally update the other syslog parameters to suit your needs. +syslog-enabled no + +# Set the number of databases. The default database is DB 0, you can select +# a different one on a per-connection basis using SELECT <dbid> where +# dbid is a number between 0 and 'databases'-1 +databases 2 + +# Snapshotting can be completely disabled with a single empty string argument +# as in following example: +# +save "" + +# The working directory. +# +# The DB will be written inside this directory, with the filename specified +# above using the 'dbfilename' configuration directive. +# +# The Append Only File will also be created inside this directory. +# +# Note that you must specify a directory here, not a file name. +dir . + +### +### Rest of the default Redis settings ####################################### +### + +bind 127.0.0.1 -::1 + +# When protected mode is on and the default user has no password, the server +# only accepts local connections from the IPv4 address (127.0.0.1), IPv6 address +# (::1) or Unix domain sockets. +protected-mode yes + +# TCP listen() backlog. +# +# In high requests-per-second environments you need a high backlog in order +# to avoid slow clients connection issues. Note that the Linux kernel +# will silently truncate it to the value of /proc/sys/net/core/somaxconn so +# make sure to raise both the value of somaxconn and tcp_max_syn_backlog +# in order to get the desired effect. +tcp-backlog 511 + +# Close the connection after a client is idle for N seconds (0 to disable) +timeout 0 + +# TCP keepalive. +# A reasonable value for this option is 300 seconds, which is the new +# Redis default starting with Redis 3.2.1. +tcp-keepalive 300 + +# By default Redis shows an ASCII art logo only when started to log to the +# standard output and if the standard output is a TTY and syslog logging is +# disabled. Basically this means that normally a logo is displayed only in +# interactive sessions. +# +# However it is possible to force the pre-4.0 behavior and always show a +# ASCII art logo in startup logs by setting the following option to yes. +always-show-logo no + +# By default, Redis modifies the process title (as seen in 'top' and 'ps') to +# provide some runtime information. It is possible to disable this and leave +# the process name as executed by setting the following to no. +set-proc-title yes + +# When changing the process title, Redis uses the following template to construct +# the modified title. +# +# Template variables are specified in curly brackets. The following variables are +# supported: +# +# {title} Name of process as executed if parent, or type of child process. +# {listen-addr} Bind address or '*' followed by TCP or TLS port listening on, or +# Unix socket if only that's available. +# {server-mode} Special mode, i.e. "[sentinel]" or "[cluster]". +# {port} TCP port listening on, or 0. +# {tls-port} TLS port listening on, or 0. +# {unixsocket} Unix domain socket listening on, or "". +# {config-file} Name of configuration file used. +# +proc-title-template "{title} {listen-addr} {server-mode}" + +# Set the local environment which is used for string comparison operations, and +# also affect the performance of Lua scripts. Empty String indicates the locale +# is derived from the environment variables. +#locale-collate "" + +# By default Redis will stop accepting writes if RDB snapshots are enabled +# (at least one save point) and the latest background save failed. +# This will make the user aware (in a hard way) that data is not persisting +# on disk properly, otherwise chances are that no one will notice and some +# disaster will happen. +# +# If the background saving process will start working again Redis will +# automatically allow writes again. +# +# However if you have setup your proper monitoring of the Redis server +# and persistence, you may want to disable this feature so that Redis will +# continue to work as usual even if there are problems with disk, +# permissions, and so forth. +stop-writes-on-bgsave-error yes + +# Compress string objects using LZF when dump .rdb databases? +# By default compression is enabled as it's almost always a win. +# If you want to save some CPU in the saving child set it to 'no' but +# the dataset will likely be bigger if you have compressible values or keys. +rdbcompression yes + +# Since version 5 of RDB a CRC64 checksum is placed at the end of the file. +# This makes the format more resistant to corruption but there is a performance +# hit to pay (around 10%) when saving and loading RDB files, so you can disable it +# for maximum performances. +# +# RDB files created with checksum disabled have a checksum of zero that will +# tell the loading code to skip the check. +rdbchecksum yes + +# The filename where to dump the DB +dbfilename redis.rdb + +# Remove RDB files used by replication in instances without persistence +# enabled. By default this option is disabled, however there are environments +# where for regulations or other security concerns, RDB files persisted on +# disk by masters in order to feed replicas, or stored on disk by replicas +# in order to load them for the initial synchronization, should be deleted +# ASAP. Note that this option ONLY WORKS in instances that have both AOF +# and RDB persistence disabled, otherwise is completely ignored. +# +# An alternative (and sometimes better) way to obtain the same effect is +# to use diskless replication on both master and replicas instances. However +# in the case of replicas, diskless is not always an option. +rdb-del-sync-files no + +# When a replica loses its connection with the master, or when the replication +# is still in progress, the replica can act in two different ways: +# +# 1) if replica-serve-stale-data is set to 'yes' (the default) the replica will +# still reply to client requests, possibly with out of date data, or the +# data set may just be empty if this is the first synchronization. +# +# 2) If replica-serve-stale-data is set to 'no' the replica will reply with error +# "MASTERDOWN Link with MASTER is down and replica-serve-stale-data is set to 'no'" +# to all data access commands, excluding commands such as: +# INFO, REPLICAOF, AUTH, SHUTDOWN, REPLCONF, ROLE, CONFIG, SUBSCRIBE, +# UNSUBSCRIBE, PSUBSCRIBE, PUNSUBSCRIBE, PUBLISH, PUBSUB, COMMAND, POST, +# HOST and LATENCY. +# +replica-serve-stale-data yes + +# You can configure a replica instance to accept writes or not. Writing against +# a replica instance may be useful to store some ephemeral data (because data +# written on a replica will be easily deleted after resync with the master) but +# may also cause problems if clients are writing to it because of a +# misconfiguration. +# +# Since Redis 2.6 by default replicas are read-only. +# +# Note: read only replicas are not designed to be exposed to untrusted clients +# on the internet. It's just a protection layer against misuse of the instance. +# Still a read only replica exports by default all the administrative commands +# such as CONFIG, DEBUG, and so forth. To a limited extent you can improve +# security of read only replicas using 'rename-command' to shadow all the +# administrative / dangerous commands. +replica-read-only yes + +# Replication SYNC strategy: disk or socket. +# +# New replicas and reconnecting replicas that are not able to continue the +# replication process just receiving differences, need to do what is called a +# "full synchronization". An RDB file is transmitted from the master to the +# replicas. +# +# The transmission can happen in two different ways: +# +# 1) Disk-backed: The Redis master creates a new process that writes the RDB +# file on disk. Later the file is transferred by the parent +# process to the replicas incrementally. +# 2) Diskless: The Redis master creates a new process that directly writes the +# RDB file to replica sockets, without touching the disk at all. +# +# With disk-backed replication, while the RDB file is generated, more replicas +# can be queued and served with the RDB file as soon as the current child +# producing the RDB file finishes its work. With diskless replication instead +# once the transfer starts, new replicas arriving will be queued and a new +# transfer will start when the current one terminates. +# +# When diskless replication is used, the master waits a configurable amount of +# time (in seconds) before starting the transfer in the hope that multiple +# replicas will arrive and the transfer can be parallelized. +# +# With slow disks and fast (large bandwidth) networks, diskless replication +# works better. +repl-diskless-sync yes + +# When diskless replication is enabled, it is possible to configure the delay +# the server waits in order to spawn the child that transfers the RDB via socket +# to the replicas. +# +# This is important since once the transfer starts, it is not possible to serve +# new replicas arriving, that will be queued for the next RDB transfer, so the +# server waits a delay in order to let more replicas arrive. +# +# The delay is specified in seconds, and by default is 5 seconds. To disable +# it entirely just set it to 0 seconds and the transfer will start ASAP. +repl-diskless-sync-delay 5 + +# When diskless replication is enabled with a delay, it is possible to let +# the replication start before the maximum delay is reached if the maximum +# number of replicas expected have connected. Default of 0 means that the +# maximum is not defined and Redis will wait the full delay. +#repl-diskless-sync-max-replicas 0 + +# ----------------------------------------------------------------------------- +# WARNING: Since in this setup the replica does not immediately store an RDB on +# disk, it may cause data loss during failovers. RDB diskless load + Redis +# modules not handling I/O reads may cause Redis to abort in case of I/O errors +# during the initial synchronization stage with the master. +# ----------------------------------------------------------------------------- +# +# Replica can load the RDB it reads from the replication link directly from the +# socket, or store the RDB to a file and read that file after it was completely +# received from the master. +# +# In many cases the disk is slower than the network, and storing and loading +# the RDB file may increase replication time (and even increase the master's +# Copy on Write memory and replica buffers). +# However, when parsing the RDB file directly from the socket, in order to avoid +# data loss it's only safe to flush the current dataset when the new dataset is +# fully loaded in memory, resulting in higher memory usage. +# For this reason we have the following options: +# +# "disabled" - Don't use diskless load (store the rdb file to the disk first) +# "swapdb" - Keep current db contents in RAM while parsing the data directly +# from the socket. Replicas in this mode can keep serving current +# dataset while replication is in progress, except for cases where +# they can't recognize master as having a data set from same +# replication history. +# Note that this requires sufficient memory, if you don't have it, +# you risk an OOM kill. +# "on-empty-db" - Use diskless load only when current dataset is empty. This is +# safer and avoid having old and new dataset loaded side by side +# during replication. +repl-diskless-load disabled + +# Master send PINGs to its replicas in a predefined interval. It's possible to +# change this interval with the repl_ping_replica_period option. The default +# value is 10 seconds. +# +# repl-ping-replica-period 10 + +# The following option sets the replication timeout for: +# +# 1) Bulk transfer I/O during SYNC, from the point of view of replica. +# 2) Master timeout from the point of view of replicas (data, pings). +# 3) Replica timeout from the point of view of masters (REPLCONF ACK pings). +# +# It is important to make sure that this value is greater than the value +# specified for repl-ping-replica-period otherwise a timeout will be detected +# every time there is low traffic between the master and the replica. The default +# value is 60 seconds. +# +# repl-timeout 60 + +# Disable TCP_NODELAY on the replica socket after SYNC? +# +# If you select "yes" Redis will use a smaller number of TCP packets and +# less bandwidth to send data to replicas. But this can add a delay for +# the data to appear on the replica side, up to 40 milliseconds with +# Linux kernels using a default configuration. +# +# If you select "no" the delay for data to appear on the replica side will +# be reduced but more bandwidth will be used for replication. +# +# By default we optimize for low latency, but in very high traffic conditions +# or when the master and replicas are many hops away, turning this to "yes" may +# be a good idea. +repl-disable-tcp-nodelay no + +# The replica priority is an integer number published by Redis in the INFO +# output. It is used by Redis Sentinel in order to select a replica to promote +# into a master if the master is no longer working correctly. +# +# A replica with a low priority number is considered better for promotion, so +# for instance if there are three replicas with priority 10, 100, 25 Sentinel +# will pick the one with priority 10, that is the lowest. +# +# However a special priority of 0 marks the replica as not able to perform the +# role of master, so a replica with priority of 0 will never be selected by +# Redis Sentinel for promotion. +# +# By default the priority is 100. +replica-priority 100 + +# ACL LOG +# +# The ACL Log tracks failed commands and authentication events associated +# with ACLs. The ACL Log is useful to troubleshoot failed commands blocked +# by ACLs. The ACL Log is stored in memory. You can reclaim memory with +# ACL LOG RESET. Define the maximum entry length of the ACL Log below. +acllog-max-len 128 + +lazyfree-lazy-eviction no +lazyfree-lazy-expire no +lazyfree-lazy-server-del no +replica-lazy-flush no + +# It is also possible, for the case when to replace the user code DEL calls +# with UNLINK calls is not easy, to modify the default behavior of the DEL +# command to act exactly like UNLINK, using the following configuration +# directive: +lazyfree-lazy-user-del no + +# FLUSHDB, FLUSHALL, SCRIPT FLUSH and FUNCTION FLUSH support both asynchronous and synchronous +# deletion, which can be controlled by passing the [SYNC|ASYNC] flags into the +# commands. When neither flag is passed, this directive will be used to determine +# if the data should be deleted asynchronously. +lazyfree-lazy-user-flush no + +# On Linux, it is possible to hint the kernel OOM killer on what processes +# should be killed first when out of memory. +# +# Enabling this feature makes Redis actively control the oom_score_adj value +# for all its processes, depending on their role. The default scores will +# attempt to have background child processes killed before all others, and +# replicas killed before masters. +# +# Redis supports these options: +# +# no: Don't make changes to oom-score-adj (default). +# yes: Alias to "relative" see below. +# absolute: Values in oom-score-adj-values are written as is to the kernel. +# relative: Values are used relative to the initial value of oom_score_adj when +# the server starts and are then clamped to a range of -1000 to 1000. +# Because typically the initial value is 0, they will often match the +# absolute values. +oom-score-adj no + +# When oom-score-adj is used, this directive controls the specific values used +# for master, replica and background child processes. Values range -2000 to +# 2000 (higher means more likely to be killed). +# +# Unprivileged processes (not root, and without CAP_SYS_RESOURCE capabilities) +# can freely increase their value, but not decrease it below its initial +# settings. This means that setting oom-score-adj to "relative" and setting the +# oom-score-adj-values to positive values will always succeed. +oom-score-adj-values 0 200 800 + +# Usually the kernel Transparent Huge Pages control is set to "madvise" or +# or "never" by default (/sys/kernel/mm/transparent_hugepage/enabled), in which +# case this config has no effect. On systems in which it is set to "always", +# redis will attempt to disable it specifically for the redis process in order +# to avoid latency problems specifically with fork(2) and CoW. +# If for some reason you prefer to keep it enabled, you can set this config to +# "no" and the kernel global to "always". +disable-thp yes + +# By default Redis asynchronously dumps the dataset on disk. This mode is +# good enough in many applications, but an issue with the Redis process or +# a power outage may result into a few minutes of writes lost (depending on +# the configured save points). +# +# The Append Only File is an alternative persistence mode that provides +# much better durability. For instance using the default data fsync policy +# (see later in the config file) Redis can lose just one second of writes in a +# dramatic event like a server power outage, or a single write if something +# wrong with the Redis process itself happens, but the operating system is +# still running correctly. +# +# AOF and RDB persistence can be enabled at the same time without problems. +# If the AOF is enabled on startup Redis will load the AOF, that is the file +# with the better durability guarantees. +# +# Please check https://redis.io/topics/persistence for more information. +appendonly no + +# The following time is expressed in microseconds, so 1000000 is equivalent +# to one second. Note that a negative number disables the slow log, while +# a value of zero forces the logging of every command. +slowlog-log-slower-than 10000 + +# There is no limit to this length. Just be aware that it will consume memory. +# You can reclaim memory used by the slow log with SLOWLOG RESET. +slowlog-max-len 128 + +# By default latency monitoring is disabled since it is mostly not needed +# if you don't have latency issues, and collecting data has a performance +# impact, that while very small, can be measured under big load. Latency +# monitoring can easily be enabled at runtime using the command +# "CONFIG SET latency-monitor-threshold <milliseconds>" if needed. +latency-monitor-threshold 0 + +# By default all notifications are disabled because most users don't need +# this feature and the feature has some overhead. Note that if you don't +# specify at least one of K or E, no events will be delivered. +notify-keyspace-events "" + +# Hashes are encoded using a memory efficient data structure when they have a +# small number of entries, and the biggest entry does not exceed a given +# threshold. These thresholds can be configured using the following directives. +#hash-max-listpack-entries 512 +#hash-max-listpack-value 64 + +# Lists are also encoded in a special way to save a lot of space. +# The number of entries allowed per internal list node can be specified +# as a fixed maximum size or a maximum number of elements. +# For a fixed maximum size, use -5 through -1, meaning: +# -5: max size: 64 Kb <-- not recommended for normal workloads +# -4: max size: 32 Kb <-- not recommended +# -3: max size: 16 Kb <-- probably not recommended +# -2: max size: 8 Kb <-- good +# -1: max size: 4 Kb <-- good +# Positive numbers mean store up to _exactly_ that number of elements +# per list node. +# The highest performing option is usually -2 (8 Kb size) or -1 (4 Kb size), +# but if your use case is unique, adjust the settings as necessary. +#list-max-listpack-size -2 + +# Lists may also be compressed. +# Compress depth is the number of quicklist ziplist nodes from *each* side of +# the list to *exclude* from compression. The head and tail of the list +# are always uncompressed for fast push/pop operations. Settings are: +# 0: disable all list compression +# 1: depth 1 means "don't start compressing until after 1 node into the list, +# going from either the head or tail" +# So: [head]->node->node->...->node->[tail] +# [head], [tail] will always be uncompressed; inner nodes will compress. +# 2: [head]->[next]->node->node->...->node->[prev]->[tail] +# 2 here means: don't compress head or head->next or tail->prev or tail, +# but compress all nodes between them. +# 3: [head]->[next]->[next]->node->node->...->node->[prev]->[prev]->[tail] +# etc. +list-compress-depth 0 + +# Sets have a special encoding when a set is composed +# of just strings that happen to be integers in radix 10 in the range +# of 64 bit signed integers. +# The following configuration setting sets the limit in the size of the +# set in order to use this special memory saving encoding. +set-max-intset-entries 512 + +# Sets containing non-integer values are also encoded using a memory efficient +# data structure when they have a small number of entries, and the biggest entry +# does not exceed a given threshold. These thresholds can be configured using +# the following directives. +#set-max-listpack-entries 128 +#set-max-listpack-value 64 + +# Similarly to hashes and lists, sorted sets are also specially encoded in +# order to save a lot of space. This encoding is only used when the length and +# elements of a sorted set are below the following limits: +#zset-max-listpack-entries 128 +#zset-max-listpack-value 64 + +# HyperLogLog sparse representation bytes limit. The limit includes the +# 16 bytes header. When a HyperLogLog using the sparse representation crosses +# this limit, it is converted into the dense representation. +# +# A value greater than 16000 is totally useless, since at that point the +# dense representation is more memory efficient. +# +# The suggested value is ~ 3000 in order to have the benefits of +# the space efficient encoding without slowing down too much PFADD, +# which is O(N) with the sparse encoding. The value can be raised to +# ~ 10000 when CPU is not a concern, but space is, and the data set is +# composed of many HyperLogLogs with cardinality in the 0 - 15000 range. +hll-sparse-max-bytes 3000 + +# Streams macro node max size / items. The stream data structure is a radix +# tree of big nodes that encode multiple items inside. Using this configuration +# it is possible to configure how big a single node can be in bytes, and the +# maximum number of items it may contain before switching to a new node when +# appending new stream entries. If any of the following settings are set to +# zero, the limit is ignored, so for instance it is possible to set just a +# max entries limit by setting max-bytes to 0 and max-entries to the desired +# value. +stream-node-max-bytes 4096 +stream-node-max-entries 100 + +# Active rehashing uses 1 millisecond every 100 milliseconds of CPU time in +# order to help rehashing the main Redis hash table (the one mapping top-level +# keys to values). The hash table implementation Redis uses (see dict.c) +# performs a lazy rehashing: the more operation you run into a hash table +# that is rehashing, the more rehashing "steps" are performed, so if the +# server is idle the rehashing is never complete and some more memory is used +# by the hash table. +# +# The default is to use this millisecond 10 times every second in order to +# actively rehash the main dictionaries, freeing memory when possible. +# +# If unsure: +# use "activerehashing no" if you have hard latency requirements and it is +# not a good thing in your environment that Redis can reply from time to time +# to queries with 2 milliseconds delay. +# +# use "activerehashing yes" if you don't have such hard requirements but +# want to free memory asap when possible. +activerehashing yes + +# The client output buffer limits can be used to force disconnection of clients +# that are not reading data from the server fast enough for some reason (a +# common reason is that a Pub/Sub client can't consume messages as fast as the +# publisher can produce them). +# +# Both the hard or the soft limit can be disabled by setting them to zero. +client-output-buffer-limit normal 0 0 0 +client-output-buffer-limit replica 256mb 64mb 60 +client-output-buffer-limit pubsub 32mb 8mb 60 + +# Redis calls an internal function to perform many background tasks, like +# closing connections of clients in timeout, purging expired keys that are +# never requested, and so forth. +# +# Not all tasks are performed with the same frequency, but Redis checks for +# tasks to perform according to the specified "hz" value. +# +# By default "hz" is set to 10. Raising the value will use more CPU when +# Redis is idle, but at the same time will make Redis more responsive when +# there are many keys expiring at the same time, and timeouts may be +# handled with more precision. +# +# The range is between 1 and 500, however a value over 100 is usually not +# a good idea. Most users should use the default of 10 and raise this up to +# 100 only in environments where very low latency is required. +hz 10 + +# When dynamic HZ is enabled, the actual configured HZ will be used +# as a baseline, but multiples of the configured HZ value will be actually +# used as needed once more clients are connected. In this way an idle +# instance will use very little CPU time while a busy instance will be +# more responsive. +dynamic-hz yes + +# When a child rewrites the AOF file, if the following option is enabled +# the file will be fsync-ed every 4 MB of data generated. This is useful +# in order to commit the file to the disk more incrementally and avoid +# big latency spikes. +aof-rewrite-incremental-fsync yes + +# When redis saves RDB file, if the following option is enabled +# the file will be fsync-ed every 4 MB of data generated. This is useful +# in order to commit the file to the disk more incrementally and avoid +# big latency spikes. +rdb-save-incremental-fsync yes + +# Jemalloc background thread for purging will be enabled by default +jemalloc-bg-thread yes diff --git a/testdata/redis_replica.tdir/redis_replica.conf b/testdata/redis_replica.tdir/redis_replica.conf new file mode 100644 index 000000000000..3a558e2337b8 --- /dev/null +++ b/testdata/redis_replica.tdir/redis_replica.conf @@ -0,0 +1,31 @@ +server: + verbosity: 7 + num-threads: 1 + interface: 127.0.0.1 + port: @PORT@ + use-syslog: no + directory: "" + pidfile: "unbound.pid" + chroot: "" + username: "" + module-config: "cachedb iterator" + root-key-sentinel: no + trust-anchor-signaling: no +cachedb: + backend: redis + redis-server-path: @REDIS_SOCKET@ + redis-replica-server-path: @REDIS_REPLICA_SOCKET@ +auth-zone: + name: "redis.com" + for-upstream: yes + for-downstream: no + zonefile: "redis.zone" +remote-control: + control-enable: yes + control-interface: 127.0.0.1 + # control-interface: ::1 + control-port: @CONTROL_PORT@ + server-key-file: "unbound_server.key" + server-cert-file: "unbound_server.pem" + control-key-file: "unbound_control.key" + control-cert-file: "unbound_control.pem" diff --git a/testdata/redis_replica.tdir/redis_replica.dsc b/testdata/redis_replica.tdir/redis_replica.dsc new file mode 100644 index 000000000000..03321f11b2b4 --- /dev/null +++ b/testdata/redis_replica.tdir/redis_replica.dsc @@ -0,0 +1,16 @@ +BaseName: redis_replica +Version: 1.0 +Description: Test redis replica operation +CreationDate: Fri 01 Mar 15:29:09 CET 2024 +Maintainer: Yorgos Thessalonikefs +Category: +Component: +CmdDepends: +Depends: +Help: +Pre: redis_replica.pre +Post: redis_replica.post +Test: redis_replica.test +AuxFiles: +Passed: +Failure: diff --git a/testdata/redis_replica.tdir/redis_replica.post b/testdata/redis_replica.tdir/redis_replica.post new file mode 100644 index 000000000000..35f11651808f --- /dev/null +++ b/testdata/redis_replica.tdir/redis_replica.post @@ -0,0 +1,18 @@ +# #-- redis_replica.post --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# source the test var file when it's there +[ -f .tpkg.var.test ] && source .tpkg.var.test +# +# do your teardown here +. ../common.sh +kill_pid $REDIS_PID +kill_pid $REDIS_REPLICA_PID +kill_pid $UNBOUND_PID +echo "> cat logfiles" +echo "redis server.log" +cat server.log +echo "redis replica.log" +cat replica.log +echo "unbound.log" +cat unbound.log diff --git a/testdata/redis_replica.tdir/redis_replica.pre b/testdata/redis_replica.tdir/redis_replica.pre new file mode 100644 index 000000000000..28ccd7b86d6c --- /dev/null +++ b/testdata/redis_replica.tdir/redis_replica.pre @@ -0,0 +1,46 @@ +# #-- redis_replica.pre--# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +PRE="../.." +. ../common.sh + +if grep "define USE_REDIS 1" $PRE/config.h; then echo test enabled; else skip_test "test skipped"; fi + +get_random_port 2 +UNBOUND_PORT=$RND_PORT +CONTROL_PORT=$(($RND_PORT + 1)) +echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test +echo "CONTROL_PORT=$CONTROL_PORT" >> .tpkg.var.test + +REDIS_SOCKET=server.sock +REDIS_REPLICA_SOCKET=replica.sock +echo "REDIS_SOCKET=$REDIS_SOCKET" >> .tpkg.var.test +echo "REDIS_REPLICA_SOCKET=$REDIS_REPLICA_SOCKET" >> .tpkg.var.test + +# start redis +sed -e 's/@SOCKET\@/'$REDIS_SOCKET'/' -e 's/@LOGFILE\@/server.log/' < redis.conf > server.conf +redis-server server.conf & +REDIS_PID=$! +echo "REDIS_PID=$REDIS_PID" >> .tpkg.var.test + +# start redis replica +sed -e 's/@SOCKET\@/'$REDIS_REPLICA_SOCKET'/' -e 's/@LOGFILE\@/replica.log/' < redis.conf > replica.conf +redis-server replica.conf & +REDIS_REPLICA_PID=$! +echo "REDIS_REPLICA_PID=$REDIS_REPLICA_PID" >> .tpkg.var.test + +# Copy initial zonefile +cp before.zone redis.zone + +# make config file +sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@REDIS_SOCKET\@/'$REDIS_SOCKET'/' -e 's/@REDIS_REPLICA_SOCKET\@/'$REDIS_REPLICA_SOCKET'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < redis_replica.conf > ub.conf +# start unbound in the background +$PRE/unbound -d -c ub.conf >unbound.log 2>&1 & +UNBOUND_PID=$! +echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test + +cat .tpkg.var.test +wait_unbound_up unbound.log diff --git a/testdata/redis_replica.tdir/redis_replica.test b/testdata/redis_replica.tdir/redis_replica.test new file mode 100644 index 000000000000..a9f15b8094f8 --- /dev/null +++ b/testdata/redis_replica.tdir/redis_replica.test @@ -0,0 +1,78 @@ +# #-- redis_replica.test --# +# source the master var file when it's there +[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master +# use .tpkg.var.test for in test variable passing +[ -f .tpkg.var.test ] && source .tpkg.var.test + +PRE="../.." +# do the test + +# Check number of keys in the db +# $1: socket to connect to +# $2: expected number of keys +redis_cli_check_keys () { + echo "> redis-cli connecting to $1 to check number of keys; expecting $2" + keys=$(redis-cli --no-raw -s $1 keys "*" | grep -vF empty | wc -l) + if test $keys -ne $2 + then + echo "Expected $2 keys, got $keys" + exit 1 + fi + echo "OK" +} + +# Query and check the expected result +# $1: query +# $2: expected answer +expect_answer () { + echo "> dig @127.0.0.1 -p $UNBOUND_PORT $1" + dig @127.0.0.1 -p $UNBOUND_PORT $1 > tmp.answer + if ! grep -F $2 tmp.answer + then + echo "Expected $2 in the answer, got:" + cat tmp.answer + exit 1 + fi + echo "OK" +} + +# Start test + +# check Redis server has no keys +redis_cli_check_keys $REDIS_SOCKET 0 + +# check Redis replica server has no keys +redis_cli_check_keys $REDIS_REPLICA_SOCKET 0 + +# query and check answer +expect_answer redis.com 1.1.1.1 + +# check Redis server has 1 key +redis_cli_check_keys $REDIS_SOCKET 1 + +# check Redis replica server has no keys +redis_cli_check_keys $REDIS_REPLICA_SOCKET 0 + +# change auth zone and reload +cp after.zone redis.zone +echo "$PRE/unbound-control -c ub.conf reload" +$PRE/unbound-control -c ub.conf reload +if test $? -ne 0; then + echo "wrong exit value after success" + exit 1 +fi + +# query and check answer +# we are writing to server but reading from replica; which is not actually +# replicating so the new answer will come through while overwriting the record +# in the server. +expect_answer redis.com 2.2.2.2 + +# check Redis server has 1 key +redis_cli_check_keys $REDIS_SOCKET 1 + +# check Redis replica server has no keys +redis_cli_check_keys $REDIS_REPLICA_SOCKET 0 + +echo "> OK" +exit 0 diff --git a/testdata/redis_replica.tdir/unbound_control.key b/testdata/redis_replica.tdir/unbound_control.key new file mode 100644 index 000000000000..753a4ef6162e --- /dev/null +++ b/testdata/redis_replica.tdir/unbound_control.key @@ -0,0 +1,39 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIG4gIBAAKCAYEAstEp+Pyh8XGrtZ77A4FhYjvbeB3dMa7Q2rGWxobzlA9przhA +1aChAvUtCOAuM+rB6NTNB8YWfZJbQHawyMNpmC77cg6vXLYCGUQHZyAqidN049RJ +F5T7j4N8Vniv17LiRdr0S6swy4PRvEnIPPV43EQHZqC5jVvHsKkhIfmBF/Dj5TXR +ypeawWV/m5jeU6/4HRYMfytBZdO1mPXuWLh0lgbQ4SCbgrOUVD3rniMk1yZIbQOm +vlDHYqekjDb/vOW2KxUQLG04aZMJ1mWfdbwG0CKQkSjISEDZ1l76vhM6mTM0fwXb +IvyFZ9yPPCle1mF5aSlxS2cmGuGVSRQaw8XF9fe3a9ACJJTr33HdSpyaZkKRAUzL +cKqLCl323daKv3NwwAT03Tj4iQM416ASMoiyfFa/2GWTKQVjddu8Crar7tGaf5xr +lig4DBmrBvdYA3njy72/RD71hLwmlRoCGU7dRuDr9O6KASUm1Ri91ONZ/qdjMvov +15l2vj4GV+KXR00dAgMBAAECggGAHepIL1N0dEQkCdpy+/8lH54L9WhpnOo2HqAf +LU9eaKK7d4jdr9+TkD8cLaPzltPrZNxVALvu/0sA4SP6J1wpyj/x6P7z73qzly5+ +Xo5PD4fEwmi9YaiW/UduAblnEZrnp/AddptJKoL/D5T4XtpiQddPtael4zQ7kB57 +YIexRSQTvEDovA/o3/nvA0TrzOxfgd4ycQP3iOWGN/TMzyLsvjydrUwbOB567iz9 +whL3Etdgvnwh5Sz2blbFfH+nAR8ctvFFz+osPvuIVR21VMEI6wm7kTpSNnQ6sh/c +lrLb/bTADn4g7z/LpIZJ+MrLvyEcoqValrLYeFBhM9CV8woPxvkO2P3pU47HVGax +tC7GV6a/kt5RoKFd/TNdiA3OC7NGZtaeXv9VkPf4fVwBtSO9d5ZZXTGEynDD/rUQ +U4KFJe6OD23APjse08HiiKqTPhsOneOONU67iqoaTdIkT2R4EdlkVEDpXVtWb+G9 +Q+IqYzVljlzuyHrhWXLJw/FMa2aBAoHBAOnZbi4gGpH+P6886WDWVgIlTccuXoyc +Mg9QQYk9UDeXxL0AizR5bZy49Sduegz9vkHpAiZARQsUnizHjZ8YlRcrmn4t6tx3 +ahTIKAjdprnxJfYINM580j8CGbXvX5LhIlm3O267D0Op+co3+7Ujy+cjsIuFQrP+ +1MqMgXSeBjzC1APivmps7HeFE+4w0k2PfN5wSMDNCzLo99PZuUG5XZ93OVOS5dpN +b+WskdcD8NOoJy/X/5A08veEI/jYO/DyqQKBwQDDwUQCOWf41ecvJLtBHKmEnHDz +ftzHino9DRKG8a9XaN4rmetnoWEaM2vHGX3pf3mwH+dAe8vJdAQueDhBKYeEpm6C +TYNOpou1+Zs5s99BilCTNYo8fkMOAyqwRwmz9zgHS6QxXuPwsghKefLJGt6o6RFF +tfWVTfLlYJ+I3GQe3ySsk3wjVz4oUTKiyiq5+KzD+HhEkS7u+RQ7Z0ZI2xd2cF8Y +aN2hjKDpcOiFf3CDoqka5D1qMNLgIHO52AHww1UCgcA1h7o7AMpURRka6hyaODY0 +A4oMYEbwdQjYjIyT998W+rzkbu1us6UtzQEBZ760npkgyU/epbOoV63lnkCC/MOU +LD0PST+L/CHiY/cWIHb79YG1EifUZKpUFg0Aoq0EGFkepF0MefGCkbRGYA5UZr9U +R80wAu9D+L+JJiS0J0BSRF74DL196zUuHt5zFeXuLzxsRtPAnq9DliS08BACRYZy +7H3I7cWD9Vn5/0jbKWHFcaaWwyETR6uekTcSzZzbCRECgcBeoE3/xUA9SSk34Mmj +7/cB4522Ft0imA3+9RK/qJTZ7Bd5fC4PKjOGNtUiqW/0L2rjeIiQ40bfWvWqgPKw +jSK1PL6uvkl6+4cNsFsYyZpiVDoe7wKju2UuoNlB3RUTqa2r2STFuNj2wRjA57I1 +BIgdnox65jqQsd14g/yaa+75/WP9CE45xzKEyrtvdcqxm0Pod3OrsYK+gikFjiar +kT0GQ8u0QPzh2tjt/2ZnIfOBrl+QYERP0MofDZDjhUdq2wECgcB0Lu841+yP5cdR +qbJhXO4zJNh7oWNcJlOuQp3ZMNFrA1oHpe9pmLukiROOy01k9WxIMQDzU5GSqRv3 +VLkYOIcbhJ3kClKAcM3j95SkKbU2H5/RENb3Ck52xtl4pNU1x/3PnVFZfDVuuHO9 +MZ9YBcIeK98MyP2jr5JtFKnOyPE7xKq0IHIhXadpbc2wjje5FtZ1cUtMyEECCXNa +C1TpXebHGyXGpY9WdWXhjdE/1jPvfS+uO5WyuDpYPr339gsdq1g= +-----END RSA PRIVATE KEY----- diff --git a/testdata/redis_replica.tdir/unbound_control.pem b/testdata/redis_replica.tdir/unbound_control.pem new file mode 100644 index 000000000000..a1edf7017f1d --- /dev/null +++ b/testdata/redis_replica.tdir/unbound_control.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDszCCAhsCFGD5193whHQ2bVdzbaQfdf1gc4SkMA0GCSqGSIb3DQEBCwUAMBIx +EDAOBgNVBAMMB3VuYm91bmQwHhcNMjAwNzA4MTMzMjMwWhcNNDAwMzI1MTMzMjMw +WjAaMRgwFgYDVQQDDA91bmJvdW5kLWNvbnRyb2wwggGiMA0GCSqGSIb3DQEBAQUA +A4IBjwAwggGKAoIBgQCy0Sn4/KHxcau1nvsDgWFiO9t4Hd0xrtDasZbGhvOUD2mv +OEDVoKEC9S0I4C4z6sHo1M0HxhZ9kltAdrDIw2mYLvtyDq9ctgIZRAdnICqJ03Tj +1EkXlPuPg3xWeK/XsuJF2vRLqzDLg9G8Scg89XjcRAdmoLmNW8ewqSEh+YEX8OPl +NdHKl5rBZX+bmN5Tr/gdFgx/K0Fl07WY9e5YuHSWBtDhIJuCs5RUPeueIyTXJkht +A6a+UMdip6SMNv+85bYrFRAsbThpkwnWZZ91vAbQIpCRKMhIQNnWXvq+EzqZMzR/ +Bdsi/IVn3I88KV7WYXlpKXFLZyYa4ZVJFBrDxcX197dr0AIklOvfcd1KnJpmQpEB +TMtwqosKXfbd1oq/c3DABPTdOPiJAzjXoBIyiLJ8Vr/YZZMpBWN127wKtqvu0Zp/ +nGuWKDgMGasG91gDeePLvb9EPvWEvCaVGgIZTt1G4Ov07ooBJSbVGL3U41n+p2My ++i/XmXa+PgZX4pdHTR0CAwEAATANBgkqhkiG9w0BAQsFAAOCAYEAd++Wen6l8Ifj +4h3p/y16PhSsWJWuJ4wdNYy3/GM84S26wGjzlEEwiW76HpH6VJzPOiBAeWnFKE83 +hFyetEIxgJeIPbcs9ZP/Uoh8GZH9tRISBSN9Hgk2Slr9llo4t1H0g/XTgA5HqMQU +9YydlBh43G7Vw3FVwh09OM6poNOGQKNc/tq2/QdKeUMtyBbLWpRmjH5XcCT35fbn +ZiVOUldqSHD4kKrFO4nJYXZyipRbcXybsLiX9GP0GLemc3IgIvOXyJ2RPp06o/SJ +pzlMlkcAfLJaSuEW57xRakhuNK7m051TKKzJzIEX+NFYOVdafFHS8VwGrYsdrFvD +72tMfu+Fu55y3awdWWGc6YlaGogZiuMnJkvQphwgn+5qE/7CGEckoKEsH601rqIZ +muaIc85+nEcHJeijd/ZlBN9zeltjFoMuqTUENgmv8+tUAdVm/UMY9Vjme6b43ydP +uv6DS02+k9z8toxXworLiPr94BGaiGV1NxgwZKLZigYJt/Fi2Qte +-----END CERTIFICATE----- diff --git a/testdata/redis_replica.tdir/unbound_server.key b/testdata/redis_replica.tdir/unbound_server.key new file mode 100644 index 000000000000..370a7bbb2f22 --- /dev/null +++ b/testdata/redis_replica.tdir/unbound_server.key @@ -0,0 +1,39 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIG5AIBAAKCAYEAvjSVSN2QMXudpzukdLCqgg/IOhCX8KYkD0FFFfWcQjgKq5wI +0x41iG32a6wbGanre4IX7VxaSPu9kkHfnGgynCk5nwDRedE/FLFhAU78PoT0+Nqq +GRS7XVQ24vLmIz9Hqc2Ozx1um1BXBTmIT0UfN2e22I0LWQ6a3seZlEDRj45gnk7Z +uh9MDgotaBdm+v1JAbupSf6Zis4VEH3JNdvVGE3O1DHEIeuuz/3BDhpf6WBDH+8K +WaBe1ca4TZHr9ThL2gEMEfAQl0wXDwRWRoi3NjNMH+mw0L1rjwThI5GXqNIee7o5 +FzUReSXZuTdFMyGe3Owcx+XoYnwi6cplSNoGsDBu4B9bKKglR9YleJVw4L4Xi8xP +q6O9UPj4+nypHk/DOoC7DIM3ufN0yxPBsFo5TVowxfhdjZXJbbftd2TZv7AH8+XL +A5UoZgRzXgzECelXSCTBFlMTnT48LfA9pMLydyjAz2UdPHs5Iv+TK5nnI+aJoeaP +7kFZSngxdy1+A/bNAgMBAAECggGBALpTOIqQwVg4CFBylL/a8K1IWJTI/I65sklf +XxYL7G7SB2HlEJ//z+E+F0+S4Vlao1vyLQ5QkgE82pAUB8FoMWvY1qF0Y8A5wtm6 +iZSGk4OLK488ZbT8Ii9i+AGKgPe2XbVxsJwj8N4k7Zooqec9hz73Up8ATEWJkRz7 +2u7oMGG4z91E0PULA64dOi3l/vOQe5w/Aa+CwVbAWtI05o7kMvQEBMDJn6C7CByo +MB5op9wueJMnz7PM7hns+U7Dy6oE4ljuolJUy51bDzFWwoM54cRoQqLFNHd8JVQj +WxldCkbfF43iyprlsEcUrTyUjtdA+ZeiG39vg/mtdmgNpGmdupHJZQvSuG8IcVlz +O+eMSeQS1QXPD6Ik8UK4SU0h+zOl8xIWtRrsxQuh4fnTN40udm/YUWl/6gOebsBI +IrVLlKGqJSfB3tMjpCRqdTzJ0dA9keVpkqm2ugZkxEf1+/efq/rFIQ2pUBLCqNTN +qpNqruK8y8FphP30I2uI4Ej2UIB8AQKBwQDd2Yptj2FyDyaXCycsyde0wYkNyzGU +dRnzdibfHnMZwjgTjwAwgIUBVIS8H0/z7ZJQKN7osJfddMrtjJtYYUk9g/dCpHXs +bNh2QSoWah3FdzNGuWd0iRf9+LFxhjAAMo/FS8zFJAJKrFsBdCGTfFUMdsLC0bjr +YjiWBuvV72uKf8XIZX5KIZruKdWBBcWukcb21R1UDyFYyXRBsly5XHaIYKZql3km +7pV7MKWO0IYgHbHIqGUqPQlzZ/lkunS1jKECgcEA23wHffD6Ou9/x3okPx2AWpTr +gh8rgqbyo6hQkBW5Y90Wz824cqaYebZDaBR/xlVx/YwjKkohv8Bde2lpH/ZxRZ1Z +5Sk2s6GJ/vU0L9RsJZgCgj4L6Coal1NMxuZtCXAlnOpiCdxSZgfqbshbTVz30KsG +ZJG361Cua1ScdAHxlZBxT52/1Sm0zRC2hnxL7h4qo7Idmtzs40LAJvYOKekR0pPN +oWeJfra7vgx/jVNvMFWoOoSLpidVO4g+ot4ery6tAoHAdW3rCic1C2zdnmH28Iw+ +s50l8Lk3mz+I5wgJd1zkzCO0DxZIoWPGA3g7cmCYr6N3KRsZMs4W9NAXgjpFGDkW +zYsG3K21BdpvkdjYcFjnPVjlOXB2RIc0vehf9Jl02wXoeCSxVUDEPcaRvWk9RJYx +ZpGOchUU7vNkxHURbIJ4yCzuAi9G8/Jp0dsu+kaV5tufF5SjG5WOrzKjaQsCbdN1 +oqaWMCHRrTvov/Z2C+xwsptFOdN5CSyZzg6hQiI4GMlBAoHAXyb6KINcOEi0YMp3 +BFXJ23tMTnEs78tozcKeipigcsbaqORK3omS+NEnj+uzKUzJyl4CsMbKstK2tFYS +mSTCHqgE3PBtIpsZtEqhgUraR8IK9GPpzZDTTl9ynZgwFTNlWw3RyuyVXF56J+T8 +kCGJ3hEHCHqT/ZRQyX85BKIDFhA0z4tYKxWVqIFiYBNq56R0X9tMMmMs36mEnF93 +7Ht6mowxTZQRa7nU0qOgeKh/P7ki4Zus3y+WJ+T9IqahLtlRAoHBAIhqMrcxSAB8 +RpB9jukJlAnidw2jCMPgrFE8tP0khhVvGrXMldxAUsMKntDIo8dGCnG1KTcWDI0O +jepvSPHSsxVLFugL79h0eVIS5z4huW48i9xgU8VlHdgAcgEPIAOFcOw2BCu/s0Vp +O+MM/EyUOdo3NsibB3qc/GJI6iNBYS7AljYEVo6rXo5V/MZvZUF4vClen6Obzsre +MTTb+4sJjfqleWuvr1XNMeu2mBfXBQkWGZP1byBK0MvD/aQ2PWq92A== +-----END RSA PRIVATE KEY----- diff --git a/testdata/redis_replica.tdir/unbound_server.pem b/testdata/redis_replica.tdir/unbound_server.pem new file mode 100644 index 000000000000..986807310f2b --- /dev/null +++ b/testdata/redis_replica.tdir/unbound_server.pem @@ -0,0 +1,22 @@ +-----BEGIN CERTIFICATE----- +MIIDqzCCAhMCFBHWXeQ6ZIa9QcQbXLFfC6tj+KA+MA0GCSqGSIb3DQEBCwUAMBIx +EDAOBgNVBAMMB3VuYm91bmQwHhcNMjAwNzA4MTMzMjI5WhcNNDAwMzI1MTMzMjI5 +WjASMRAwDgYDVQQDDAd1bmJvdW5kMIIBojANBgkqhkiG9w0BAQEFAAOCAY8AMIIB +igKCAYEAvjSVSN2QMXudpzukdLCqgg/IOhCX8KYkD0FFFfWcQjgKq5wI0x41iG32 +a6wbGanre4IX7VxaSPu9kkHfnGgynCk5nwDRedE/FLFhAU78PoT0+NqqGRS7XVQ2 +4vLmIz9Hqc2Ozx1um1BXBTmIT0UfN2e22I0LWQ6a3seZlEDRj45gnk7Zuh9MDgot +aBdm+v1JAbupSf6Zis4VEH3JNdvVGE3O1DHEIeuuz/3BDhpf6WBDH+8KWaBe1ca4 +TZHr9ThL2gEMEfAQl0wXDwRWRoi3NjNMH+mw0L1rjwThI5GXqNIee7o5FzUReSXZ +uTdFMyGe3Owcx+XoYnwi6cplSNoGsDBu4B9bKKglR9YleJVw4L4Xi8xPq6O9UPj4 ++nypHk/DOoC7DIM3ufN0yxPBsFo5TVowxfhdjZXJbbftd2TZv7AH8+XLA5UoZgRz +XgzECelXSCTBFlMTnT48LfA9pMLydyjAz2UdPHs5Iv+TK5nnI+aJoeaP7kFZSngx +dy1+A/bNAgMBAAEwDQYJKoZIhvcNAQELBQADggGBABunf93MKaCUHiZgnoOTinsW +84/EgInrgtKzAyH+BhnKkJOhhR0kkIAx5d9BpDlaSiRTACFon9moWCgDIIsK/Ar7 +JE0Kln9cV//wiiNoFU0O4mnzyGUIMvlaEX6QHMJJQYvL05+w/3AAcf5XmMJtR5ca +fJ8FqvGC34b2WxX9lTQoyT52sRt+1KnQikiMEnEyAdKktMG+MwKsFDdOwDXyZhZg +XZhRrfX3/NVJolqB6EahjWIGXDeKuSSKZVtCyib6LskyeMzN5lcRfvubKDdlqFVF +qlD7rHBsKhQUWK/IO64mGf7y/de+CgHtED5vDvr/p2uj/9sABATfbrOQR3W/Of25 +sLBj4OEfrJ7lX8hQgFaxkMI3x6VFT3W8dTCp7xnQgb6bgROWB5fNEZ9jk/gjSRmD +yIU+r0UbKe5kBk/CmZVFXL2TyJ92V5NYEQh8V4DGy19qZ6u/XKYyNJL4ocs35GGe +CA8SBuyrmdhx38h1RHErR2Skzadi1S7MwGf1y431fQ== +-----END CERTIFICATE----- diff --git a/testdata/rpz_nsdname.rpl b/testdata/rpz_nsdname.rpl index a4e9bb31d30e..661f5da2c345 100644 --- a/testdata/rpz_nsdname.rpl +++ b/testdata/rpz_nsdname.rpl @@ -32,7 +32,7 @@ stub-zone: stub-addr: 1.1.1.1 CONFIG_END -SCENARIO_BEGIN Test RPZ nsip triggers +SCENARIO_BEGIN Test RPZ nsdname triggers ; . -------------------------------------------------------------------------- RANGE_BEGIN 0 100 diff --git a/testdata/rpz_val_block.rpl b/testdata/rpz_val_block.rpl index acde15294adb..d2cd897e09e7 100644 --- a/testdata/rpz_val_block.rpl +++ b/testdata/rpz_val_block.rpl @@ -6,7 +6,6 @@ server: trust-anchor: "org. DS 1444 8 2 5224fb17d630a2e3efdc863a05a4032c5db415b5de3f32472ee9abed42e10146" val-override-date: "20070916134226" trust-anchor-signaling: no - log-servfail: yes val-log-level: 2 ede: yes diff --git a/testdata/serve_expired.rpl b/testdata/serve_expired.rpl index 3f61019fa89f..990a562c7191 100644 --- a/testdata/serve_expired.rpl +++ b/testdata/serve_expired.rpl @@ -4,6 +4,7 @@ server: qname-minimisation: "no" minimal-responses: no serve-expired: yes + serve-expired-client-timeout: 0 access-control: 127.0.0.1/32 allow_snoop ede: yes ede-serve-expired: yes diff --git a/testdata/serve_expired_0ttl_nodata.rpl b/testdata/serve_expired_0ttl_nodata.rpl index 7f1b5a565853..8ca461be2c7b 100644 --- a/testdata/serve_expired_0ttl_nodata.rpl +++ b/testdata/serve_expired_0ttl_nodata.rpl @@ -4,7 +4,7 @@ server: qname-minimisation: "no" minimal-responses: no serve-expired: yes - log-servfail: yes + serve-expired-client-timeout: 0 ede: yes ede-serve-expired: yes diff --git a/testdata/serve_expired_0ttl_nxdomain.rpl b/testdata/serve_expired_0ttl_nxdomain.rpl index 4adb4b839a69..7cf26aedda0a 100644 --- a/testdata/serve_expired_0ttl_nxdomain.rpl +++ b/testdata/serve_expired_0ttl_nxdomain.rpl @@ -4,7 +4,7 @@ server: qname-minimisation: "no" minimal-responses: no serve-expired: yes - log-servfail: yes + serve-expired-client-timeout: 0 ede: yes ede-serve-expired: yes diff --git a/testdata/serve_expired_0ttl_servfail.rpl b/testdata/serve_expired_0ttl_servfail.rpl index 6833af17b827..e9d4c4884e9f 100644 --- a/testdata/serve_expired_0ttl_servfail.rpl +++ b/testdata/serve_expired_0ttl_servfail.rpl @@ -4,7 +4,7 @@ server: qname-minimisation: "no" minimal-responses: no serve-expired: yes - log-servfail: yes + serve-expired-client-timeout: 0 ede: yes ede-serve-expired: yes diff --git a/testdata/serve_expired_cached_servfail.rpl b/testdata/serve_expired_cached_servfail.rpl index edec7447940f..eb115816ec1d 100644 --- a/testdata/serve_expired_cached_servfail.rpl +++ b/testdata/serve_expired_cached_servfail.rpl @@ -4,8 +4,8 @@ server: qname-minimisation: "no" minimal-responses: no serve-expired: yes + serve-expired-client-timeout: 0 serve-expired-reply-ttl: 123 - log-servfail: yes ede: yes ede-serve-expired: yes diff --git a/testdata/serve_expired_cached_servfail_refresh.rpl b/testdata/serve_expired_cached_servfail_refresh.rpl index 4d14dd948ffb..63277f25f15e 100644 --- a/testdata/serve_expired_cached_servfail_refresh.rpl +++ b/testdata/serve_expired_cached_servfail_refresh.rpl @@ -4,8 +4,8 @@ server: qname-minimisation: "no" minimal-responses: no serve-expired: yes + serve-expired-client-timeout: 0 serve-expired-reply-ttl: 123 - log-servfail: yes ede: yes ede-serve-expired: yes diff --git a/testdata/serve_expired_client_timeout_servfail.rpl b/testdata/serve_expired_client_timeout_servfail.rpl index cea216d4c60f..3c5b35e1793a 100644 --- a/testdata/serve_expired_client_timeout_servfail.rpl +++ b/testdata/serve_expired_client_timeout_servfail.rpl @@ -6,11 +6,9 @@ server: serve-expired: yes serve-expired-client-timeout: 1 serve-expired-reply-ttl: 123 - log-servfail: yes ede: yes ede-serve-expired: yes - stub-zone: name: "example.com" stub-addr: 1.2.3.4 @@ -26,8 +24,10 @@ SCENARIO_BEGIN Test serve-expired with client-timeout and a SERVFAIL upstream re ; - check that we get the expired cached answer ; - query again (the answer is available on the upstream server now) ; - check that we get the immediate expired answer back instead -; - (the upstream query does happen after the expired reply and updates the cache) -; - query again (the upstream has no answer) +; - query again (the answer is available on the upstream server now) +; - check that we *still* get the immediate expired answer back instead, recursion is blocked for NORR_TTL(5) +; - wait for NORR_TTL(5) to expire +; - query again ; - check that we get the freshly cached answer ; ns.example.com. @@ -74,7 +74,7 @@ RANGE_BEGIN 30 40 RANGE_END ; ns.example.com. -RANGE_BEGIN 50 60 +RANGE_BEGIN 50 100 ADDRESS 1.2.3.4 ; response to A query ENTRY_BEGIN @@ -149,12 +149,8 @@ ENTRY_BEGIN example.com. IN A ENTRY_END -; Allow for upstream query to resolve. -STEP 51 TRAFFIC - ; Check that we got an immediate stale answer because of the previous failure, -; regardless if upstream has the answer already in this range. The query will -; be resolved after the immediate cached answer and will cache the result. +; regardless if upstream has the answer already in this range. STEP 60 CHECK_ANSWER ENTRY_BEGIN MATCH all ttl ede=3 @@ -172,15 +168,42 @@ ENTRY_END ; Query again STEP 70 QUERY ENTRY_BEGIN - REPLY RD + REPLY RD DO SECTION QUESTION example.com. IN A ENTRY_END -; Check that we got the cached updated answer from the previous step since -; there is no upstream in this range. +; Check that we still get the immediate stale answer because of the previous failure, +; regardless if upstream has the answer already in this range. NORR_TTL(5) blocks us from +; recursion. STEP 80 CHECK_ANSWER ENTRY_BEGIN + MATCH all ttl ede=3 + REPLY QR RD RA DO NOERROR + SECTION QUESTION + example.com. IN A + SECTION ANSWER + example.com. 123 IN A 5.6.7.8 + SECTION AUTHORITY + example.com. 123 IN NS ns.example.com. + SECTION ADDITIONAL + ns.example.com. 123 IN A 1.2.3.4 +ENTRY_END + +; Let NORR_TTL(5) expire +STEP 81 TIME_PASSES ELAPSE 5 + +; Query again +STEP 90 QUERY +ENTRY_BEGIN + REPLY RD + SECTION QUESTION + example.com. IN A +ENTRY_END + +; Check fresh reply +STEP 100 CHECK_ANSWER +ENTRY_BEGIN MATCH all ttl REPLY QR RD RA NOERROR SECTION QUESTION diff --git a/testdata/serve_expired_client_timeout_val_bogus.rpl b/testdata/serve_expired_client_timeout_val_bogus.rpl index f4937a16c538..47a6545a4035 100644 --- a/testdata/serve_expired_client_timeout_val_bogus.rpl +++ b/testdata/serve_expired_client_timeout_val_bogus.rpl @@ -30,13 +30,22 @@ SCENARIO_BEGIN Test serve-expired with client-timeout and bogus answer ; - wait for the record to expire ; - (upstream now has a bogus response) ; - query again for www.example.com. IN A -; - check that we get the expired valid response instead -; - query once more +; - check that we get the expired valid response instead; recursion is blocked for NORR_TTL(5) because of the failure ; - (upstream has the valid response again) +; - query once more ; - check that we get the immediate expired valid response -; - (the prefetch query updates the cache with the valid response) +; - let NORR_TTL(5) expire ; - query one last time -; - check that we get the immediate valid cache response; upstream does not have an answer at this moment +; - check that we get the immediate valid cache response + +; The example.com NS and ns.example.com A record are commented out. +; This to make the test succeed. It then keeps the dnssec valid lookup. +; Otherwise, the relookup of the referral would overwrite the example.com NS +; the serve expired response would no longer be valid. But this record must +; be cached, for keeping the current delegation information. +; Also the DNSKEY lookup authority and additional are cleaned to stop overwrite +; of the NS and A record. This is more likely to keep the serve expired +; information intact. ;; ;; K.ROOT-SERVERS.NET. @@ -150,12 +159,12 @@ RANGE_BEGIN 0 10 www.example.com. IN A SECTION ANSWER www.example.com. IN A 10.20.30.40 - ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} + ;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} SECTION AUTHORITY - example.com. IN NS ns.example.com. - example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} + ;example.com. IN NS ns.example.com. + ;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} SECTION ADDITIONAL - ns.example.com. IN A 1.2.3.4 + ;ns.example.com. IN A 1.2.3.4 www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} ENTRY_END RANGE_END @@ -174,12 +183,12 @@ RANGE_BEGIN 20 30 www.example.com. IN A SECTION ANSWER www.example.com. IN A 10.20.30.40 - ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} + ;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} SECTION AUTHORITY - example.com. IN NS ns.example.com. - example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} + ;example.com. IN NS ns.example.com. + ;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} SECTION ADDITIONAL - ns.example.com. IN A 1.2.3.4 + ;ns.example.com. IN A 1.2.3.4 ;; (valid signature) ;; www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} ;; (bogus signature) @@ -190,7 +199,7 @@ RANGE_END ;; ;; ns.example.com. with valid data again ;; -RANGE_BEGIN 40 60 +RANGE_BEGIN 40 70 ADDRESS 1.2.3.4 ; response to query of interest ENTRY_BEGIN @@ -201,12 +210,12 @@ RANGE_BEGIN 40 60 www.example.com. IN A SECTION ANSWER www.example.com. IN A 10.20.30.40 - ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} + ;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} SECTION AUTHORITY - example.com. IN NS ns.example.com. - example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} + ;example.com. IN NS ns.example.com. + ;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} SECTION ADDITIONAL - ns.example.com. IN A 1.2.3.4 + ;ns.example.com. IN A 1.2.3.4 www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} ENTRY_END RANGE_END @@ -229,11 +238,11 @@ SECTION ANSWER www.example.com. IN A 10.20.30.40 www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} SECTION AUTHORITY -example.com. IN NS ns.example.com. -example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +;example.com. IN NS ns.example.com. +;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} SECTION ADDITIONAL -ns.example.com. IN A 1.2.3.4 -ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} +;ns.example.com. IN A 1.2.3.4 +;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} ENTRY_END STEP 11 TIME_PASSES ELAPSE 3601 @@ -256,11 +265,11 @@ SECTION ANSWER www.example.com. 123 IN A 10.20.30.40 www.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} SECTION AUTHORITY -example.com. 123 IN NS ns.example.com. -example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +;example.com. 123 IN NS ns.example.com. +;example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} SECTION ADDITIONAL -ns.example.com. 123 IN A 1.2.3.4 -ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} +;ns.example.com. 123 IN A 1.2.3.4 +;ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} ENTRY_END STEP 40 QUERY @@ -270,7 +279,7 @@ SECTION QUESTION www.example.com. IN A ENTRY_END -; immediate cached answer because upstream is valid again +; immediate cached answer; although upstream is valid again STEP 50 CHECK_ANSWER ENTRY_BEGIN MATCH all ttl ede=3 @@ -281,14 +290,16 @@ SECTION ANSWER www.example.com. 123 IN A 10.20.30.40 www.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} SECTION AUTHORITY -example.com. 123 IN NS ns.example.com. -example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +;example.com. 123 IN NS ns.example.com. +;example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} SECTION ADDITIONAL -ns.example.com. 123 IN A 1.2.3.4 -ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} +;ns.example.com. 123 IN A 1.2.3.4 +;ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} ENTRY_END -; upstream query is resolved before this query comes in +STEP 51 TIME_PASSES ELAPSE 5 + +; query one last time STEP 60 QUERY ENTRY_BEGIN REPLY RD DO @@ -296,7 +307,7 @@ SECTION QUESTION www.example.com. IN A ENTRY_END -; prefetch query updated the cache, since there is no upstream response in this range +; this is the fresh valid response STEP 70 CHECK_ANSWER ENTRY_BEGIN MATCH all ttl @@ -307,11 +318,11 @@ SECTION ANSWER www.example.com. IN A 10.20.30.40 www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} SECTION AUTHORITY -example.com. IN NS ns.example.com. -example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +;example.com. IN NS ns.example.com. +;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} SECTION ADDITIONAL -ns.example.com. IN A 1.2.3.4 -ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} +;ns.example.com. IN A 1.2.3.4 +;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} ENTRY_END SCENARIO_END diff --git a/testdata/serve_expired_reply_ttl.rpl b/testdata/serve_expired_reply_ttl.rpl index 124fb874df0e..e76976bde07d 100644 --- a/testdata/serve_expired_reply_ttl.rpl +++ b/testdata/serve_expired_reply_ttl.rpl @@ -5,6 +5,7 @@ server: minimal-responses: no serve-expired: yes serve-expired-reply-ttl: 123 + serve-expired-client-timeout: 0 ede: yes ede-serve-expired: yes diff --git a/testdata/serve_expired_ttl.rpl b/testdata/serve_expired_ttl.rpl index df4ecb89d48a..66acbdcf1fe1 100644 --- a/testdata/serve_expired_ttl.rpl +++ b/testdata/serve_expired_ttl.rpl @@ -4,6 +4,7 @@ server: qname-minimisation: "no" minimal-responses: no serve-expired: yes + serve-expired-client-timeout: 0 serve-expired-ttl: 10 stub-zone: diff --git a/testdata/serve_expired_ttl_reset.rpl b/testdata/serve_expired_ttl_reset.rpl index 521d5a0f04ca..9f215c96bcd1 100644 --- a/testdata/serve_expired_ttl_reset.rpl +++ b/testdata/serve_expired_ttl_reset.rpl @@ -4,6 +4,7 @@ server: serve-expired-ttl: 1 serve-expired-ttl-reset: yes serve-expired-reply-ttl: 123 + serve-expired-client-timeout: 0 ede: yes ede-serve-expired: yes forward-zone: name: "." forward-addr: 216.0.0.1 @@ -15,11 +16,11 @@ SCENARIO_BEGIN Serve expired ttl with reset on forwarder with a timeout on upstr ; - Wait for it to expire (+ serve-expired-ttl) ; - Send query again ; - Upstream timeouts -; - Error response from iterator SERVFAIL, resets expired-ttl on cache -; - Check we are getting the SERVFAIL response +; - Error response from iterator SERVFAIL, resets expired-ttl on cache and sets norec_ttl blocking recursion +; - Check we are getting the cached response because it was expired-ttl-reset ; - Query again -; - Check we are getting the expired answer -; - Upstream still timeouts +; - Check we are getting the expired answer; prefetching is blocked by norec_ttl +; - If there was prefetching the test would fail with the pending upstream query STEP 1 QUERY ENTRY_BEGIN @@ -53,7 +54,7 @@ STEP 4 TIME_PASSES ELAPSE 12 STEP 5 QUERY ENTRY_BEGIN -REPLY RD +REPLY RD DO SECTION QUESTION www.example.com. IN A ENTRY_END @@ -66,14 +67,16 @@ STEP 8 TIMEOUT STEP 9 TIMEOUT STEP 10 TIMEOUT -; Returns servfail +; Returns ; but error response from iterator resets the expired ttl STEP 11 CHECK_ANSWER ENTRY_BEGIN -MATCH all ttl -REPLY QR RA RD SERVFAIL +MATCH all ttl ede=3 +REPLY QR RA RD DO NOERROR SECTION QUESTION www.example.com. IN A +SECTION ANSWER +www.example.com. 123 IN A 0.0.0.0 ENTRY_END ; Query again @@ -95,8 +98,4 @@ SECTION ANSWER www.example.com. 123 IN A 0.0.0.0 ENTRY_END -; But the pending query times out! -; Only one because RTT reached the limit. -STEP 16 TIMEOUT - SCENARIO_END diff --git a/testdata/serve_expired_val_bogus.rpl b/testdata/serve_expired_val_bogus.rpl index 35365beef973..54b66fe98800 100644 --- a/testdata/serve_expired_val_bogus.rpl +++ b/testdata/serve_expired_val_bogus.rpl @@ -10,6 +10,7 @@ server: minimal-responses: no serve-expired: yes + serve-expired-client-timeout: 0 serve-expired-reply-ttl: 123 ede: yes ede-serve-expired: yes @@ -30,12 +31,27 @@ SCENARIO_BEGIN Test serve-expired with client-timeout and bogus answer ; - (upstream now has a bogus response) ; - query again for www.example.com. IN A ; - check that we get the immediate expired valid response -; - (prefetch response is bogus and is not cached) +; - (prefetch response is bogus and is not cached; recursion is blocked for NORR_TTL(5) because of the failure) +; - (upstream has a valid response again) ; - query once more -; - check that we still get the immediate expired valid response and not the fresh bogus one -; - (upstream has a valid response again; prefetch will update the cache) +; - check that we still get the immediate expired valid response (prefetch will not trigger because of NORR_TTL(5)) +; - query and check that cache was not updated +; - let NORR_TTL(5) expire +; - query once more +; - check that we still get the immediate expired valid response +; - (prefetch should be allowed to refresh the record at this point) +; - (upstream does not have the answer anymore) ; - query one last time -; - check that we get an immediate valid cache response +; - check that we get the immediate valid cache response + +; The example.com NS and ns.example.com A record are commented out. +; This to make the test succeed. It then keeps the dnssec valid lookup. +; Otherwise, the relookup of the referral would overwrite the example.com NS +; the serve expired response would no longer be valid. But this record must +; be cached, for keeping the current delegation information. +; Also the DNSKEY lookup authority and additional are cleaned to stop overwrite +; of the NS and A record. This is more likely to keep the serve expired +; information intact. ;; ;; K.ROOT-SERVERS.NET. @@ -149,12 +165,12 @@ RANGE_BEGIN 0 10 www.example.com. IN A SECTION ANSWER www.example.com. IN A 10.20.30.40 - ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} + ;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} SECTION AUTHORITY - example.com. IN NS ns.example.com. - example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} + ;example.com. IN NS ns.example.com. + ;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} SECTION ADDITIONAL - ns.example.com. IN A 1.2.3.4 + ;ns.example.com. IN A 1.2.3.4 www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} ENTRY_END RANGE_END @@ -173,12 +189,12 @@ RANGE_BEGIN 20 40 www.example.com. IN A SECTION ANSWER www.example.com. IN A 10.20.30.40 - ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} + ;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} SECTION AUTHORITY - example.com. IN NS ns.example.com. - example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} + ;example.com. IN NS ns.example.com. + ;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} SECTION ADDITIONAL - ns.example.com. IN A 1.2.3.4 + ;ns.example.com. IN A 1.2.3.4 ;; (valid signature) ;; www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} ;; (bogus signature) @@ -200,12 +216,12 @@ RANGE_BEGIN 50 100 www.example.com. IN A SECTION ANSWER www.example.com. IN A 10.20.30.40 - ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} + ;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} SECTION AUTHORITY - example.com. IN NS ns.example.com. - example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} + ;example.com. IN NS ns.example.com. + ;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} SECTION ADDITIONAL - ns.example.com. IN A 1.2.3.4 + ;ns.example.com. IN A 1.2.3.4 www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} ENTRY_END RANGE_END @@ -229,11 +245,11 @@ SECTION ANSWER www.example.com. IN A 10.20.30.40 www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} SECTION AUTHORITY -example.com. IN NS ns.example.com. -example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +;example.com. IN NS ns.example.com. +;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} SECTION ADDITIONAL -ns.example.com. IN A 1.2.3.4 -ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} +;ns.example.com. IN A 1.2.3.4 +;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} ENTRY_END STEP 11 TIME_PASSES ELAPSE 3601 @@ -256,13 +272,14 @@ SECTION ANSWER www.example.com. 123 IN A 10.20.30.40 www.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} SECTION AUTHORITY -example.com. 123 IN NS ns.example.com. -example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +;example.com. 123 IN NS ns.example.com. +;example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} SECTION ADDITIONAL -ns.example.com. 123 IN A 1.2.3.4 -ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} +;ns.example.com. 123 IN A 1.2.3.4 +;ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} ENTRY_END +; query with response available on the server STEP 40 QUERY ENTRY_BEGIN REPLY RD DO @@ -270,7 +287,8 @@ SECTION QUESTION www.example.com. IN A ENTRY_END -; this is still the immediate cache response because the previous upstream response was bogus +; this is still the immediate expired cache response because the previous upstream response was bogus +; upstream query did not go out because of the previous failure NORR_TTL(5). STEP 50 CHECK_ANSWER ENTRY_BEGIN MATCH all ttl ede=3 @@ -281,13 +299,14 @@ SECTION ANSWER www.example.com. 123 IN A 10.20.30.40 www.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} SECTION AUTHORITY -example.com. 123 IN NS ns.example.com. -example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +;example.com. 123 IN NS ns.example.com. +;example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} SECTION ADDITIONAL -ns.example.com. 123 IN A 1.2.3.4 -ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} +;ns.example.com. 123 IN A 1.2.3.4 +;ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} ENTRY_END +; query with response available STEP 60 QUERY ENTRY_BEGIN REPLY RD DO @@ -295,9 +314,63 @@ SECTION QUESTION www.example.com. IN A ENTRY_END -; this is the immediate cache response because the previous upstream response was valid +; this is still the immediate expired cache response because resolution is blocked for NORR_TTL(5) STEP 70 CHECK_ANSWER ENTRY_BEGIN +MATCH all ttl ede=3 +REPLY QR RD RA AD DO NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. 123 IN A 10.20.30.40 +www.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} +SECTION AUTHORITY +;example.com. 123 IN NS ns.example.com. +;example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +SECTION ADDITIONAL +;ns.example.com. 123 IN A 1.2.3.4 +;ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} +ENTRY_END + +; expire NORR_TTL(5) +STEP 71 TIME_PASSES ELAPSE 5 + +; query again +STEP 80 QUERY +ENTRY_BEGIN +REPLY RD DO +SECTION QUESTION +www.example.com. IN A +ENTRY_END + +; this is still the immediate expired cache response but prefetching will be allowed to update the cache +STEP 90 CHECK_ANSWER +ENTRY_BEGIN +MATCH all ttl ede=3 +REPLY QR RD RA AD DO NOERROR +SECTION QUESTION +www.example.com. IN A +SECTION ANSWER +www.example.com. 123 IN A 10.20.30.40 +www.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} +SECTION AUTHORITY +;example.com. 123 IN NS ns.example.com. +;example.com. 123 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +SECTION ADDITIONAL +;ns.example.com. 123 IN A 1.2.3.4 +;ns.example.com. 123 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} +ENTRY_END + +STEP 100 QUERY +ENTRY_BEGIN +REPLY RD DO +SECTION QUESTION +www.example.com. IN A +ENTRY_END + +; this is the immediate cache response because the previous upstream response was valid +STEP 110 CHECK_ANSWER +ENTRY_BEGIN MATCH all ttl REPLY QR RD RA AD DO NOERROR SECTION QUESTION @@ -306,11 +379,11 @@ SECTION ANSWER www.example.com. IN A 10.20.30.40 www.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFC99iE9K5y2WNgI0gFvBWaTi9wm6AhUAoUqOpDtG5Zct+Qr9F3mSdnbc6V4= ;{id = 2854} SECTION AUTHORITY -example.com. IN NS ns.example.com. -example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} +;example.com. IN NS ns.example.com. +;example.com. 3600 IN RRSIG NS 3 2 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCN+qHdJxoI/2tNKwsb08pra/G7aAIUAWA5sDdJTbrXA1/3OaesGBAO3sI= ;{id = 2854} SECTION ADDITIONAL -ns.example.com. IN A 1.2.3.4 -ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} +;ns.example.com. IN A 1.2.3.4 +;ns.example.com. 3600 IN RRSIG A 3 3 3600 20070926134150 20070829134150 2854 example.com. MC0CFQCQMyTjn7WWwpwAR1LlVeLpRgZGuQIUCcJDEkwAuzytTDRlYK7nIMwH1CM= ;{id = 2854} ENTRY_END SCENARIO_END diff --git a/testdata/serve_expired_zerottl.rpl b/testdata/serve_expired_zerottl.rpl index 0239b4a19440..1411cb8e77a5 100644 --- a/testdata/serve_expired_zerottl.rpl +++ b/testdata/serve_expired_zerottl.rpl @@ -4,6 +4,7 @@ server: qname-minimisation: "no" minimal-responses: no serve-expired: yes + serve-expired-client-timeout: 0 serve-expired-reply-ttl: 123 ede: yes ede-serve-expired: yes diff --git a/testdata/serve_original_ttl.rpl b/testdata/serve_original_ttl.rpl index 24d01b6fee1e..30503c285ccd 100644 --- a/testdata/serve_original_ttl.rpl +++ b/testdata/serve_original_ttl.rpl @@ -8,6 +8,7 @@ server: cache-max-ttl: 1000 cache-min-ttl: 20 serve-expired: yes + serve-expired-client-timeout: 0 serve-expired-reply-ttl: 123 ede: yes ede-serve-expired: yes diff --git a/testdata/stat_values.tdir/stat_values.conf b/testdata/stat_values.tdir/stat_values.conf index dc4553920635..312a7e17494f 100644 --- a/testdata/stat_values.tdir/stat_values.conf +++ b/testdata/stat_values.tdir/stat_values.conf @@ -14,6 +14,10 @@ server: outbound-msg-retry: 0 root-key-sentinel: no trust-anchor-signaling: no + serve-expired-client-timeout: 0 + dns-error-reporting: yes + + trust-anchor: "bogusdnssec. DS 1444 8 2 5224fb17d630a2e3efdc863a05a4032c5db415b5de3f32472ee9abed42e10146" local-zone: local.zone static local-data: "www.local.zone A 192.0.2.1" @@ -26,9 +30,15 @@ remote-control: server-cert-file: "unbound_server.pem" control-key-file: "unbound_control.key" control-cert-file: "unbound_control.pem" -forward-zone: - name: "." - forward-addr: "127.0.0.1@@TOPORT@" -forward-zone: +stub-zone: + name: "example.com." + stub-addr: "127.0.0.1@@TOPORT@" +stub-zone: + name: "bogusdnssec." + stub-addr: "127.0.0.1@@TOPORT@" +stub-zone: + name: "an.agent." + stub-addr: "127.0.0.1@@TOPORT@" +stub-zone: name: "expired." - forward-addr: "127.0.0.1@@EXPIREDPORT@" + stub-addr: "127.0.0.1@@EXPIREDPORT@" diff --git a/testdata/stat_values.tdir/stat_values.pre b/testdata/stat_values.tdir/stat_values.pre index 7b6eefdfaa49..81f94d8d10be 100644 --- a/testdata/stat_values.tdir/stat_values.pre +++ b/testdata/stat_values.tdir/stat_values.pre @@ -38,6 +38,7 @@ echo "FWD_EXPIRED_PID=$FWD_EXPIRED_PID" >> .tpkg.var.test sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@EXPIREDPORT\@/'$FWD_EXPIRED_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < stat_values.conf > ub.conf sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@EXPIREDPORT\@/'$FWD_EXPIRED_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < stat_values_cachedb.conf > ub_cachedb.conf sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < stat_values_downstream_cookies.conf > ub_downstream_cookies.conf +sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' -e 's/@CONTROL_PORT\@/'$CONTROL_PORT'/' < stat_values_discard_wait_limit.conf > ub_discard_wait_limit.conf # start unbound in the background $PRE/unbound -d -c ub.conf >unbound.log 2>&1 & UNBOUND_PID=$! diff --git a/testdata/stat_values.tdir/stat_values.test b/testdata/stat_values.tdir/stat_values.test index 814ecd1168d3..d538e4d60ec2 100644 --- a/testdata/stat_values.tdir/stat_values.test +++ b/testdata/stat_values.tdir/stat_values.test @@ -3,7 +3,6 @@ [ -f ../.tpkg.var.master ] && source ../.tpkg.var.master # use .tpkg.var.test for in test variable passing [ -f .tpkg.var.test ] && source .tpkg.var.test -# We need kill_pid for the serve-expired-client-timeout test . ../common.sh PRE="../.." @@ -154,6 +153,19 @@ set_ub_option () { fi } +# Convenient function to kill current Unbound and bring up one with an alternate configuration. +bring_up_alternate_configuration () { + conf_file=$1 + kill_pid $UNBOUND_PID # kill current Unbound + echo "" + cat unbound.log + echo "" + $PRE/unbound -d -c $conf_file >unbound.log 2>&1 & + UNBOUND_PID=$! + echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test + wait_unbound_up unbound.log +} + # Convenient function to exit the test. end () { echo "> cat logfiles" @@ -180,8 +192,8 @@ else end 1 fi -echo -echo "[ Check initial stats based on first query. ]" + +teststep "Check initial stats based on first query." check_stats "\ total.num.queries=1 total.num.cachemiss=1 @@ -198,16 +210,15 @@ rrset.cache.count=1 infra.cache.count=1 num.answer.rcode.NOERROR=1" -echo -echo "[ Check stat reset. ]" + +teststep "Check stat reset." check_stats "\ msg.cache.count=1 rrset.cache.count=1 infra.cache.count=1" -echo -echo "[ Enable serve-expired and check. ]" +teststep "Enable serve-expired and check." set_ub_option serve-expired yes sleep 2 # make sure the TTL has expired. echo "> dig 1ttl.example.com." @@ -236,8 +247,7 @@ rrset.cache.count=1 infra.cache.count=1" -echo -echo "[ Enable serve-expired-client-timeout and check. ]" +teststep "Enable serve-expired-client-timeout and check." set_ub_option serve-expired-client-timeout 1 echo "> dig servfail.expired." dig @127.0.0.1 -p $UNBOUND_PORT servfail.expired. | tee outfile @@ -295,8 +305,7 @@ infra.cache.count=2" set_ub_option serve-expired no -echo -echo "[ Check REFUSED; try without RD flag. ]" +teststep "Check REFUSED; try without RD flag." echo "> dig somethingelse.example.com." dig @127.0.0.1 -p $UNBOUND_PORT +nordflag somethingelse.example.com. | tee outfile echo "> check answer" @@ -319,8 +328,7 @@ rrset.cache.count=2 infra.cache.count=2" -echo -echo "[ Check the AD flag. ]" +teststep "Check the AD flag." echo "> dig www.example.com." dig @127.0.0.1 -p $UNBOUND_PORT +noadflag www.example.com. | tee outfile echo "> check answer" @@ -345,8 +353,8 @@ msg.cache.count=3 rrset.cache.count=3 infra.cache.count=2" -echo -echo "[ Check local zone. ]" + +teststep "Check local zone." echo "> dig www.local.zone." dig @127.0.0.1 -p $UNBOUND_PORT www.local.zone. | tee outfile echo "> check answer" @@ -370,8 +378,7 @@ rrset.cache.count=3 infra.cache.count=2" -echo -echo "[ Check NXDOMAIN (with local data). ]" +teststep "Check NXDOMAIN (with local data)." echo "> dig mail.local.zone." dig @127.0.0.1 -p $UNBOUND_PORT mail.local.zone. | tee outfile echo "> check answer" @@ -395,8 +402,7 @@ rrset.cache.count=3 infra.cache.count=2" -echo -echo "[ Check CHAOS. ]" +teststep "Check CHAOS." echo "> dig id.server. ch txt" dig @127.0.0.1 -p $UNBOUND_PORT id.server. ch txt | tee outfile echo "> check answer" @@ -420,18 +426,79 @@ rrset.cache.count=3 infra.cache.count=2" +teststep "Check dns-error-reporting." +echo "> dig www.bogusdnssec." +dig @127.0.0.1 -p $UNBOUND_PORT www.bogusdnssec. | tee outfile +echo "> check answer" +if grep "SERVFAIL" outfile; then + echo "OK" +else + end 1 +fi +check_stats "\ +infra.cache.count=4 +key.cache.count=1 +msg.cache.count=7 +num.answer.bogus=1 +num.answer.rcode.SERVFAIL=1 +num.query.class.IN=1 +num.query.edns.present=1 +num.query.flags.AD=1 +num.query.flags.RD=1 +num.query.opcode.QUERY=1 +num.query.type.A=1 +num.query.udpout=9 +rrset.cache.count=4 +total.num.cachemiss=1 +total.num.dns_error_reports=1 +total.num.queries=1 +total.num.recursivereplies=1" + + +### +# +# Bring the discard-timeout, wait-limit configured Unbound up +# +bring_up_alternate_configuration ub_discard_wait_limit.conf +# +### + + +teststep "Check discard-timeout and wait-limit" +echo "> dig www.unresponsive" +dig @127.0.0.1 -p $UNBOUND_PORT +retry=2 +timeout=1 www.unresponsive. | tee outfile +echo "> check answer" +if grep "no servers could be reached" outfile; then + echo "OK" +else + end 1 +fi +check_stats "\ +infra.cache.count=1 +msg.cache.count=1 +num.query.class.IN=3 +num.query.edns.present=3 +num.query.flags.AD=3 +num.query.flags.RD=3 +num.query.opcode.QUERY=3 +num.query.type.A=3 +num.query.udpout=1 +total.num.cachemiss=3 +total.num.queries=3 +total.num.queries_discard_timeout=2 +total.num.queries_wait_limit=1" + + +### +# # Bring the downstream DNS Cookies configured Unbound up -kill_pid $UNBOUND_PID # kill current Unbound -echo "" -cat unbound.log -echo "" -$PRE/unbound -d -c ub_downstream_cookies.conf >unbound.log 2>&1 & -UNBOUND_PID=$! -echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test -wait_unbound_up unbound.log - -echo -echo "[ Get a DNS Cookie. ]" +# +bring_up_alternate_configuration ub_downstream_cookies.conf +# +### + + +teststep "Get a DNS Cookie." echo "> dig www.local.zone +tcp $nocookie +ednsopt=10:0102030405060708" dig @127.0.0.1 -p $UNBOUND_PORT +tcp $nocookie +ednsopt=10:0102030405060708 +retry=0 +time=1 www.local.zone. | tee outfile echo "> check answer" @@ -456,8 +523,8 @@ num.query.edns.present=1 num.query.tcp=1 num.answer.rcode.NOERROR=1" -echo -echo "[ Present the valid DNS Cookie. ]" + +teststep "Present the valid DNS Cookie." echo "> dig www.local.zone $nocookie +ednsopt=10:valid_cookie" dig @127.0.0.1 -p $UNBOUND_PORT $nocookie +ednsopt=10:$valid_cookie +retry=0 +time=1 www.local.zone. | tee outfile echo "> check answer" @@ -478,8 +545,8 @@ num.query.flags.AD=1 num.query.edns.present=1 num.answer.rcode.NOERROR=1" -echo -echo "[ Present an invalid DNS Cookie. ]" + +teststep "Present an invalid DNS Cookie." echo "> dig www.local.zone $nocookie +ednsopt=10:invalid_cookie" dig @127.0.0.1 -p $UNBOUND_PORT $nocookie +ednsopt=10:$invalid_cookie +retry=0 +time=1 www.local.zone. | tee outfile echo "> check answer" @@ -497,8 +564,8 @@ total.num.queries_cookie_invalid=1 total.num.cachehits=1 num.answer.rcode.YXRRSET=1" -echo -echo "[ Present no DNS Cookie. ]" + +teststep "Present no DNS Cookie." echo "> dig www.local.zone +ignore" dig @127.0.0.1 -p $UNBOUND_PORT +ignore $nocookie +retry=0 +time=1 www.local.zone. | tee outfile echo "> check answer" @@ -516,18 +583,17 @@ num.answer.rcode.REFUSED=1" if test x$USE_CACHEDB = "x1"; then + +### +# # Bring the cachedb configured Unbound up -kill_pid $UNBOUND_PID # kill current Unbound -echo "" -cat unbound.log -echo "" -$PRE/unbound -d -c ub_cachedb.conf >unbound.log 2>&1 & -UNBOUND_PID=$! -echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test -wait_unbound_up unbound.log - -echo -echo "[ Check cachedb cache miss. ]" +# +bring_up_alternate_configuration ub_cachedb.conf +# +### + + +teststep "Check cachedb cache miss." echo "> dig www.example.com." dig @127.0.0.1 +ednsopt=65534 -p $UNBOUND_PORT www.example.com. | tee outfile echo "> check answer" @@ -554,8 +620,8 @@ rrset.cache.count=1 infra.cache.count=1 num.answer.rcode.NOERROR=1" -echo -echo "[ Check cachedb cache hit. ]" + +teststep "Check cachedb cache hit." echo "> dig www.example.com." dig @127.0.0.1 +ednsopt=65534 -p $UNBOUND_PORT www.example.com. | tee outfile echo "> check answer" @@ -582,8 +648,8 @@ rrset.cache.count=1 infra.cache.count=1 num.answer.rcode.NOERROR=1" -echo -echo "[ Check cachedb cache hit with stat reset ]" + +teststep "Check cachedb cache hit with stat reset." echo "> dig www.example.com." dig @127.0.0.1 +ednsopt=65534 -p $UNBOUND_PORT www.example.com. | tee outfile echo "> check answer" diff --git a/testdata/stat_values.tdir/stat_values.testns b/testdata/stat_values.tdir/stat_values.testns index 12df8a93905a..a5c0ae92b599 100644 --- a/testdata/stat_values.tdir/stat_values.testns +++ b/testdata/stat_values.tdir/stat_values.testns @@ -31,3 +31,52 @@ SECTION QUESTION SECTION ANSWER 0ttl 0 IN A 0.0.0.1 ENTRY_END + + + +$ORIGIN bogusdnssec. + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA NOERROR +ADJUST copy_id +SECTION QUESTION +@ IN DNSKEY +SECTION ANSWER +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA NOERROR +ADJUST copy_id +SECTION QUESTION +www IN A +SECTION ANSWER +www 0 IN A 10.20.30.40 +; bogus signature to not trigger LAME DNSSEC and continue with validation +www 0 IN RRSIG A 8 2 240 20250429005000 20250401005000 42393 bogusdnssec. ob6ddTJkdeOUn92cxx1NPGneV7rhOp2zKBv8FXQjJ/Wso8LJJnzRHW9p 3sTatlzi+UdRi7BOrcxwjUG38lgO+TS5vRFGAiTRmOezm6xJVNTg8lIb RJGCD5bRtRRstwt31Qt6Gda+6sAyvDebpUB/opkQpevv6xohdrhr0g8+ Q4w= +SECTION ADDITIONAL +; dns error reporting agent +HEX_EDNSDATA_BEGIN + 00 12 ; opt-code (Report-Channel) + 00 0A ; opt-len + 02 61 6E 05 61 67 65 6E 74 00 ; an.agent. +HEX_EDNSDATA_END +ENTRY_END + + + +$ORIGIN an.agent. +;just give an answer back to anything +ENTRY_BEGIN +MATCH opcode subdomain +REPLY QR AA NXDOMAIN +ADJUST copy_id copy_query +SECTION QUESTION +an.agent. IN ANY +ENTRY_END + + + +$ORIGIN unresponsive. +;; no entry for 'unresponsive.', we rely on timeouts. diff --git a/testdata/stat_values.tdir/stat_values_cachedb.conf b/testdata/stat_values.tdir/stat_values_cachedb.conf index b5e9b0e02932..b7b375b36ef1 100644 --- a/testdata/stat_values.tdir/stat_values_cachedb.conf +++ b/testdata/stat_values.tdir/stat_values_cachedb.conf @@ -1,7 +1,6 @@ server: verbosity: 5 module-config: "cachedb iterator" - serve-expired: yes num-threads: 1 interface: 127.0.0.1 port: @PORT@ @@ -17,8 +16,6 @@ server: root-key-sentinel: no trust-anchor-signaling: no - local-zone: local.zone static - local-data: "www.local.zone A 192.0.2.1" remote-control: control-enable: yes control-interface: 127.0.0.1 @@ -28,9 +25,6 @@ remote-control: server-cert-file: "unbound_server.pem" control-key-file: "unbound_control.key" control-cert-file: "unbound_control.pem" -forward-zone: - name: "." - forward-addr: "127.0.0.1@@TOPORT@" -forward-zone: - name: "expired." - forward-addr: "127.0.0.1@@EXPIREDPORT@" +stub-zone: + name: "example.com." + stub-addr: "127.0.0.1@@TOPORT@" diff --git a/testdata/stat_values.tdir/stat_values_discard_wait_limit.conf b/testdata/stat_values.tdir/stat_values_discard_wait_limit.conf new file mode 100644 index 000000000000..b6f63cf17cfd --- /dev/null +++ b/testdata/stat_values.tdir/stat_values_discard_wait_limit.conf @@ -0,0 +1,36 @@ +server: + verbosity: 5 + num-threads: 1 + interface: 127.0.0.1 + module-config: "validator iterator" + port: @PORT@ + use-syslog: no + directory: "" + pidfile: "unbound.pid" + chroot: "" + username: "" + do-not-query-localhost: no + extended-statistics: yes + identity: "stat_values" + outbound-msg-retry: 0 + root-key-sentinel: no + trust-anchor-signaling: no + + discard-timeout: 800 + wait-limit: 1 + wait-limit-netblock: 127.0.0.0/8 1 + wait-limit-netblock: ::1/128 1 + infra-cache-min-rtt: 3000 # This is for the discard-timeout test + +remote-control: + control-enable: yes + control-interface: 127.0.0.1 + # control-interface: ::1 + control-port: @CONTROL_PORT@ + server-key-file: "unbound_server.key" + server-cert-file: "unbound_server.pem" + control-key-file: "unbound_control.key" + control-cert-file: "unbound_control.pem" +stub-zone: + name: "unresponsive." + stub-addr: "127.0.0.1@@TOPORT@" diff --git a/testdata/subnet_cached_servfail.crpl b/testdata/subnet_cached_servfail.crpl index 9c746d579124..f1a66159c4ee 100644 --- a/testdata/subnet_cached_servfail.crpl +++ b/testdata/subnet_cached_servfail.crpl @@ -12,6 +12,7 @@ server: qname-minimisation: no minimal-responses: no serve-expired: yes + serve-expired-client-timeout: 0 prefetch: yes stub-zone: diff --git a/testdata/subnet_global_prefetch_always_forward.crpl b/testdata/subnet_global_prefetch_always_forward.crpl index ccfe5dfd6ea1..775474cbcfeb 100644 --- a/testdata/subnet_global_prefetch_always_forward.crpl +++ b/testdata/subnet_global_prefetch_always_forward.crpl @@ -6,6 +6,7 @@ server: trust-anchor-signaling: no target-fetch-policy: "0 0 0 0 0" serve-expired: yes + serve-expired-client-timeout: 0 client-subnet-always-forward: yes module-config: "subnetcache iterator" verbosity: 3 diff --git a/testdata/subnet_global_prefetch_expired.crpl b/testdata/subnet_global_prefetch_expired.crpl index de1b780553a9..374bf3e693aa 100644 --- a/testdata/subnet_global_prefetch_expired.crpl +++ b/testdata/subnet_global_prefetch_expired.crpl @@ -14,6 +14,7 @@ server: qname-minimisation: no minimal-responses: no serve-expired: yes + serve-expired-client-timeout: 0 serve-expired-ttl: 1 prefetch: yes diff --git a/testdata/test_ldnsrr.4 b/testdata/test_ldnsrr.4 index 07c9960d5053..b20a317289b3 100644 --- a/testdata/test_ldnsrr.4 +++ b/testdata/test_ldnsrr.4 @@ -35,7 +35,8 @@ all.rr.org. IN LOC 42N 71 06 18.3W -24m 30m ; EID ; NIMLOC _http._tcp.all.rr.org. IN SRV 0 5 80 ns1.example.com. -; ATMA +atma0 IN ATMA 39.246f.00.0e7c9c.0312.0001.0001.000012345678.00 +atma1 IN ATMA +1.908.555.1212 all.rr.org. IN NAPTR 100 10 "" "" "!^urn:cid:.+@([^\\.]+\\.)(.*)$!\\2!i" . all.rr.org. IN KX 2 rt1.example.com. all.rr.org. IN CERT 6 0 0 FFsAyW1dVK7hIGuvhN56r26UwJx/ diff --git a/testdata/test_ldnsrr.5 b/testdata/test_ldnsrr.5 index 2762ca82d327..1f2837a67098 100644 --- a/testdata/test_ldnsrr.5 +++ b/testdata/test_ldnsrr.5 @@ -174,3 +174,5 @@ root-servers.net. 3600000 IN ZONEMD 2018091100 1 1 ( f1ca0ccd91bd5573d9f43 foo. 12345 IN LOC 12 45 52.333 N 105 40 33.452 W -24m 0.1m 0.1m 0.1m ; from ldns issue #147, fix #148, tab between quoted strings. foo 12345 IN HINFO "hohum" "weirdo" +0.0.3.6.1.0.0.0.f.f.f.f.f.f.3.3.1.e.1.0.0.0.0.0.0.0.0.0.a.5.0.0.0.8.5.0.0.0.7.4.NSAP.INT. IN NSAP-PTR foo.bar.com. +0.0.4.6.1.0.0.0.f.f.f.f.f.f.3.3.1.e.1.0.0.0.0.0.0.0.0.0.a.5.0.0.0.8.5.0.0.0.7.4.NSAP.INT. IN NSAP-PTR host.school.de. diff --git a/testdata/test_ldnsrr.c3 b/testdata/test_ldnsrr.c3 index 3adb7b5069ff..0ce9340dfc31 100644 --- a/testdata/test_ldnsrr.c3 +++ b/testdata/test_ldnsrr.c3 @@ -169,7 +169,7 @@ dname03.types-signed.wb.sidnlabs.nl. 3600 IN NSEC gpos.types-signed.wb.sidnlabs. 07646E616D6530330C74797065732D7369676E6564027762087369646E6C616273026E6C00002E000100000E1000AF002F080500000E1052EC3900524963DCF35A0C74797065732D7369676E6564027762087369646E6C616273026E6C00CFCE6808CE405CC73016F9685E75C161BEAA5869D2A6C9B584F4C22BD0CFE199C44F2F8C68BC7CEEF64DAEA444A78C9BB78271C487CD3A76885F757E5D98CEC0B35D173FE21040453AA59C34A6155199A9E1D8FACC67A36646021298D2F9CAEE31E2E022AB152BF32981795D796FC5532F017A091FD7928996BA1E5EF2E665DC dname03.types-signed.wb.sidnlabs.nl. 3600 IN RRSIG NSEC 8 5 3600 20140201000000 20130930114324 62298 types-signed.wb.sidnlabs.nl. z85oCM5AXMcwFvloXnXBYb6qWGnSpsm1hPTCK9DP4ZnETy+MaLx87vZNrqREp4ybt4JxxIfNOnaIX3V+XZjOwLNdFz/iEEBFOqWcNKYVUZmp4dj6zGejZkYCEpjS+cruMeLgIqsVK/MpgXldeW/FUy8Begkf15KJlroeXvLmZdw= ;{id = 62298} 0467706F730C74797065732D7369676E6564027762087369646E6C616273026E6C00001B00010000003C00120532332E36370532332E36370532332E3637 -gpos.types-signed.wb.sidnlabs.nl. 60 IN GPOS "23.67" "23.67" "23.67" +gpos.types-signed.wb.sidnlabs.nl. 60 IN GPOS 23.67 23.67 23.67 0467706F730C74797065732D7369676E6564027762087369646E6C616273026E6C00002E00010000003C00AF001B08050000003C52EC3900524963DCF35A0C74797065732D7369676E6564027762087369646E6C616273026E6C0049CBABEED1B9089695C552489294378669AE1B934A81076F364E3D3E68F239E34AC106D4554F009A39A7813B1C8E02076B0A0737DACE4CCC7BF3CD20F4DFF9C19934DAAD81F23FB743C89CA941387CFC6B1506525634206D4918FA9CBE9707A88B25B0F6FF10E295551E4643488EA87FE7E051BD9E6D8AEF42F01574BB56BEE4 gpos.types-signed.wb.sidnlabs.nl. 60 IN RRSIG GPOS 8 5 60 20140201000000 20130930114324 62298 types-signed.wb.sidnlabs.nl. Scur7tG5CJaVxVJIkpQ3hmmuG5NKgQdvNk49PmjyOeNKwQbUVU8AmjmngTscjgIHawoHN9rOTMx7880g9N/5wZk02q2B8j+3Q8icqUE4fPxrFQZSVjQgbUkY+py+lweoiyWw9v8Q4pVVHkZDSI6of+fgUb2ebYrvQvAVdLtWvuQ= ;{id = 62298} 0467706F730C74797065732D7369676E6564027762087369646E6C616273026E6C00002F000100000E10002B0568696E666F0C74797065732D7369676E6564027762087369646E6C616273026E6C000006000000100003 @@ -859,7 +859,7 @@ type26.types-signed.wb.sidnlabs.nl. 3600 IN NSEC type27.types-signed.wb.sidnlabs 067479706532360C74797065732D7369676E6564027762087369646E6C616273026E6C00002E000100000E1000AF002F080500000E1052EC3900524963DCF35A0C74797065732D7369676E6564027762087369646E6C616273026E6C00B37F1C2B73BB1D6A5EE4A53E2E9E8F893F0A4E20FD62BC7C1C56D2A40D59AC7CD25157555FC677BB9DCAA76C3F07710B381DBB61EEF2A8896A67F1AF40107DFC5BD74B62593ACFFBE407DEA015E12D72294725BDC7B8218FDC5E991A5676CC9BAC59B8A2D743F3A3A479226167D54973C7DAE32267D2AD6DE873CC8ABDCFA07E type26.types-signed.wb.sidnlabs.nl. 3600 IN RRSIG NSEC 8 5 3600 20140201000000 20130930114324 62298 types-signed.wb.sidnlabs.nl. s38cK3O7HWpe5KU+Lp6PiT8KTiD9Yrx8HFbSpA1ZrHzSUVdVX8Z3u53Kp2w/B3ELOB27Ye7yqIlqZ/GvQBB9/FvXS2JZOs/75AfeoBXhLXIpRyW9x7ghj9xemRpWdsybrFm4otdD86OkeSJhZ9VJc8fa4yJn0q1t6HPMir3PoH4= ;{id = 62298} 067479706532370C74797065732D7369676E6564027762087369646E6C616273026E6C00001B00010000003C00120532332E36370532332E36370532332E3637 -type27.types-signed.wb.sidnlabs.nl. 60 IN GPOS "23.67" "23.67" "23.67" +type27.types-signed.wb.sidnlabs.nl. 60 IN GPOS 23.67 23.67 23.67 067479706532370C74797065732D7369676E6564027762087369646E6C616273026E6C00002E00010000003C00AF001B08050000003C52EC3900524963DCF35A0C74797065732D7369676E6564027762087369646E6C616273026E6C0013BF8CA0C46CABE234D3A0D55A9D4D2A30449E21A25E889DBAE3499A2C567B8F652C2CB2F67A83767D6B5963205F7FBF83A79318E702C558E30688507E062029FCF4EBD2EC5DEE7DFEB6C3C2F326131920401A05444AAA326CC9D118139C43A4A0DC834ECE3ECF883DAC78B03031F15432A5ACD4331587F43B22176CBA0A6E14 type27.types-signed.wb.sidnlabs.nl. 60 IN RRSIG GPOS 8 5 60 20140201000000 20130930114324 62298 types-signed.wb.sidnlabs.nl. E7+MoMRsq+I006DVWp1NKjBEniGiXoiduuNJmixWe49lLCyy9nqDdn1rWWMgX3+/g6eTGOcCxVjjBohQfgYgKfz069LsXe59/rbDwvMmExkgQBoFREqqMmzJ0RgTnEOkoNyDTs4+z4g9rHiwMDHxVDKlrNQzFYf0OyIXbLoKbhQ= ;{id = 62298} 067479706532370C74797065732D7369676E6564027762087369646E6C616273026E6C00002F000100000E10002C067479706532380C74797065732D7369676E6564027762087369646E6C616273026E6C000006000000100003 diff --git a/testdata/test_ldnsrr.c4 b/testdata/test_ldnsrr.c4 index 56b87fbcbbf4..93e7617f6a80 100644 --- a/testdata/test_ldnsrr.c4 +++ b/testdata/test_ldnsrr.c4 @@ -46,6 +46,10 @@ all.rr.org. 3600 IN LOC 42 21 54.500 N 71 06 18.300 W -24m 30m 10000m 10m all.rr.org. 3600 IN LOC 42 00 00.000 N 71 06 18.300 W -24m 30m 10000m 10m 055F68747470045F74637003616C6C027272036F7267000021000100000E100017000000050050036E7331076578616D706C6503636F6D00 _http._tcp.all.rr.org. 3600 IN SRV 0 5 80 ns1.example.com. +0561746D6130000022000100000E1000150039246F000E7C9C03120001000100001234567800 +atma0. 3600 IN ATMA 39246F000E7C9C03120001000100001234567800 +0561746D6131000022000100000E10000C013139303835353531323132 +atma1. 3600 IN ATMA +19085551212 03616C6C027272036F7267000023000100000E1000290064000A000021215E75726E3A6369643A2E2B40285B5E5C2E5D2B5C2E29282E2A2924215C32216900 all.rr.org. 3600 IN NAPTR 100 10 "" "" "!^urn:cid:.+@([^\\.]+\\.)(.*)$!\\2!i" . 03616C6C027272036F7267000024000100000E100013000203727431076578616D706C6503636F6D00 diff --git a/testdata/test_ldnsrr.c5 b/testdata/test_ldnsrr.c5 index e86532c3433e..72d7b69d62bc 100644 --- a/testdata/test_ldnsrr.c5 +++ b/testdata/test_ldnsrr.c5 @@ -214,3 +214,7 @@ root-servers.net. 3600000 IN ZONEMD 2018091100 1 1 F1CA0CCD91BD5573D9F431C00EE01 foo. 12345 IN LOC 12 45 52.333 N 105 40 33.452 W -24m 0.10m 0.10m 0.10m 03666F6F00000D000100003039000D05686F68756D0677656972646F foo. 12345 IN HINFO "hohum" "weirdo" +0130013001330136013101300130013001660166016601660166016601330133013101650131013001300130013001300130013001300130016101350130013001300138013501300130013001370134044E53415003494E54000017000100000E10000D0C666F6F2E6261722E636F6D2E +0.0.3.6.1.0.0.0.f.f.f.f.f.f.3.3.1.e.1.0.0.0.0.0.0.0.0.0.a.5.0.0.0.8.5.0.0.0.7.4.NSAP.INT. 3600 IN NSAP-PTR foo.bar.com. +0130013001340136013101300130013001660166016601660166016601330133013101650131013001300130013001300130013001300130016101350130013001300138013501300130013001370134044E53415003494E54000017000100000E1000100F686F73742E7363686F6F6C2E64652E +0.0.4.6.1.0.0.0.f.f.f.f.f.f.3.3.1.e.1.0.0.0.0.0.0.0.0.0.a.5.0.0.0.8.5.0.0.0.7.4.NSAP.INT. 3600 IN NSAP-PTR host.school.de. diff --git a/testdata/val_failure_dnskey.rpl b/testdata/val_failure_dnskey.rpl index 3f25f15b2062..c5f1af2ff349 100644 --- a/testdata/val_failure_dnskey.rpl +++ b/testdata/val_failure_dnskey.rpl @@ -9,7 +9,6 @@ server: fake-sha1: yes trust-anchor-signaling: no minimal-responses: no - log-servfail: yes val-log-level: 2 ede: yes diff --git a/testdata/val_scrub_rr_length.rpl b/testdata/val_scrub_rr_length.rpl index 0219b918e421..f83157ff04c3 100644 --- a/testdata/val_scrub_rr_length.rpl +++ b/testdata/val_scrub_rr_length.rpl @@ -9,7 +9,6 @@ server: minimal-responses: no rrset-roundrobin: no ede: yes - log-servfail: yes stub-zone: name: "." diff --git a/util/config_file.c b/util/config_file.c index aca0039d487a..81bffa8d88aa 100644 --- a/util/config_file.c +++ b/util/config_file.c @@ -280,11 +280,10 @@ config_create(void) cfg->ignore_cd = 0; cfg->disable_edns_do = 0; cfg->serve_expired = 0; - cfg->serve_expired_ttl = 0; + cfg->serve_expired_ttl = 86400; cfg->serve_expired_ttl_reset = 0; cfg->serve_expired_reply_ttl = 30; - cfg->serve_expired_client_timeout = 0; - cfg->ede_serve_expired = 0; + cfg->serve_expired_client_timeout = 1800; cfg->serve_original_ttl = 0; cfg->zonemd_permissive_mode = 0; cfg->add_holddown = 30*24*3600; @@ -329,11 +328,7 @@ config_create(void) if(!(cfg->control_cert_file = strdup(RUN_DIR"/unbound_control.pem"))) goto error_exit; -#ifdef CLIENT_SUBNET - if(!(cfg->module_conf = strdup("subnetcache validator iterator"))) goto error_exit; -#else if(!(cfg->module_conf = strdup("validator iterator"))) goto error_exit; -#endif if(!(cfg->val_nsec3_key_iterations = strdup("1024 150 2048 150 4096 150"))) goto error_exit; #if defined(DNSTAP_SOCKET_PATH) @@ -399,14 +394,22 @@ config_create(void) cfg->cachedb_check_when_serve_expired = 1; #ifdef USE_REDIS if(!(cfg->redis_server_host = strdup("127.0.0.1"))) goto error_exit; + if(!(cfg->redis_replica_server_host = strdup(""))) goto error_exit; cfg->redis_server_path = NULL; + cfg->redis_replica_server_path = NULL; cfg->redis_server_password = NULL; + cfg->redis_replica_server_password = NULL; cfg->redis_timeout = 100; + cfg->redis_replica_timeout = 100; cfg->redis_command_timeout = 0; + cfg->redis_replica_command_timeout = 0; cfg->redis_connect_timeout = 0; + cfg->redis_replica_connect_timeout = 0; cfg->redis_server_port = 6379; + cfg->redis_replica_server_port = 6379; cfg->redis_expire_records = 0; cfg->redis_logical_db = 0; + cfg->redis_replica_logical_db = 0; #endif /* USE_REDIS */ #endif /* USE_CACHEDB */ #ifdef USE_IPSET @@ -414,9 +417,11 @@ config_create(void) cfg->ipset_name_v6 = NULL; #endif cfg->ede = 0; + cfg->ede_serve_expired = 0; + cfg->dns_error_reporting = 0; cfg->iter_scrub_ns = 20; cfg->iter_scrub_cname = 11; - cfg->max_global_quota = 128; + cfg->max_global_quota = 200; return cfg; error_exit: config_delete(cfg); @@ -502,6 +507,25 @@ struct config_file* config_create_forlib(void) #define S_STRLIST_APPEND(str, var) if(strcmp(opt, str)==0) \ { return cfg_strlist_append(&cfg->var, strdup(val)); } +/** Set PROBE_MAXRTO based on current RTT_MAX_TIMEOUT + * (USEFUL_SERVER_TOP_TIMEOUT) configuration. */ +static int +probe_maxrto(int useful_server_top_timeout) { + return + PROBE_MAXRTO > useful_server_top_timeout + ?useful_server_top_timeout + :PROBE_MAXRTO_DEFAULT; +} + +/** Apply the relevant changes that rely upon RTT_MAX_TIMEOUT */ +int config_apply_max_rtt(int max_rtt) +{ + USEFUL_SERVER_TOP_TIMEOUT = max_rtt; + BLACKLIST_PENALTY = max_rtt*4; + PROBE_MAXRTO = probe_maxrto(max_rtt); + return max_rtt; +} + int config_set_option(struct config_file* cfg, const char* opt, const char* val) { @@ -648,9 +672,7 @@ int config_set_option(struct config_file* cfg, const char* opt, } else if(strcmp(opt, "infra-cache-max-rtt:") == 0) { IS_NUMBER_OR_ZERO; cfg->infra_cache_max_rtt = atoi(val); - RTT_MAX_TIMEOUT=cfg->infra_cache_max_rtt; - USEFUL_SERVER_TOP_TIMEOUT = RTT_MAX_TIMEOUT; - BLACKLIST_PENALTY = USEFUL_SERVER_TOP_TIMEOUT*4; + RTT_MAX_TIMEOUT=config_apply_max_rtt(cfg->infra_cache_max_rtt); } else S_YNO("infra-keep-probing:", infra_keep_probing) else S_NUMBER_OR_ZERO("infra-host-ttl:", host_ttl) @@ -735,6 +757,7 @@ int config_set_option(struct config_file* cfg, const char* opt, else S_NUMBER_OR_ZERO("serve-expired-client-timeout:", serve_expired_client_timeout) else S_YNO("ede:", ede) else S_YNO("ede-serve-expired:", ede_serve_expired) + else S_YNO("dns-error-reporting:", dns_error_reporting) else S_NUMBER_OR_ZERO("iter-scrub-ns:", iter_scrub_ns) else S_NUMBER_OR_ZERO("iter-scrub-cname:", iter_scrub_cname) else S_NUMBER_OR_ZERO("max-global-quota:", max_global_quota) @@ -1210,6 +1233,7 @@ config_get_option(struct config_file* cfg, const char* opt, else O_DEC(opt, "serve-expired-client-timeout", serve_expired_client_timeout) else O_YNO(opt, "ede", ede) else O_YNO(opt, "ede-serve-expired", ede_serve_expired) + else O_YNO(opt, "dns-error-reporting", dns_error_reporting) else O_DEC(opt, "iter-scrub-ns", iter_scrub_ns) else O_DEC(opt, "iter-scrub-cname", iter_scrub_cname) else O_DEC(opt, "max-global-quota", max_global_quota) @@ -1375,14 +1399,22 @@ config_get_option(struct config_file* cfg, const char* opt, else O_YNO(opt, "cachedb-check-when-serve-expired", cachedb_check_when_serve_expired) #ifdef USE_REDIS else O_STR(opt, "redis-server-host", redis_server_host) + else O_STR(opt, "redis-replica-server-host", redis_replica_server_host) else O_DEC(opt, "redis-server-port", redis_server_port) + else O_DEC(opt, "redis-replica-server-port", redis_replica_server_port) else O_STR(opt, "redis-server-path", redis_server_path) + else O_STR(opt, "redis-replica-server-path", redis_replica_server_path) else O_STR(opt, "redis-server-password", redis_server_password) + else O_STR(opt, "redis-replica-server-password", redis_replica_server_password) else O_DEC(opt, "redis-timeout", redis_timeout) + else O_DEC(opt, "redis-replica-timeout", redis_replica_timeout) else O_DEC(opt, "redis-command-timeout", redis_command_timeout) + else O_DEC(opt, "redis-replica-command-timeout", redis_replica_command_timeout) else O_DEC(opt, "redis-connect-timeout", redis_connect_timeout) + else O_DEC(opt, "redis-replica-connect-timeout", redis_replica_connect_timeout) else O_YNO(opt, "redis-expire-records", redis_expire_records) else O_DEC(opt, "redis-logical-db", redis_logical_db) + else O_DEC(opt, "redis-replica-logical-db", redis_replica_logical_db) #endif /* USE_REDIS */ #endif /* USE_CACHEDB */ #ifdef USE_IPSET @@ -1718,6 +1750,7 @@ config_delete(struct config_file* cfg) config_del_strarray(cfg->tagname, cfg->num_tags); config_del_strbytelist(cfg->local_zone_tags); config_del_strbytelist(cfg->respip_tags); + config_deldblstrlist(cfg->respip_actions); config_deldblstrlist(cfg->acl_view); config_del_strbytelist(cfg->acl_tags); config_deltrplstrlist(cfg->acl_tag_actions); @@ -1761,8 +1794,11 @@ config_delete(struct config_file* cfg) free(cfg->cachedb_secret); #ifdef USE_REDIS free(cfg->redis_server_host); + free(cfg->redis_replica_server_host); free(cfg->redis_server_path); + free(cfg->redis_replica_server_path); free(cfg->redis_server_password); + free(cfg->redis_replica_server_password); #endif /* USE_REDIS */ #endif /* USE_CACHEDB */ #ifdef USE_IPSET @@ -2414,15 +2450,13 @@ config_apply(struct config_file* config) MAX_NEG_TTL = (time_t)config->max_negative_ttl; MIN_NEG_TTL = (time_t)config->min_negative_ttl; RTT_MIN_TIMEOUT = config->infra_cache_min_rtt; - RTT_MAX_TIMEOUT = config->infra_cache_max_rtt; + RTT_MAX_TIMEOUT = config_apply_max_rtt(config->infra_cache_max_rtt); EDNS_ADVERTISED_SIZE = (uint16_t)config->edns_buffer_size; MINIMAL_RESPONSES = config->minimal_responses; RRSET_ROUNDROBIN = config->rrset_roundrobin; LOG_TAG_QUERYREPLY = config->log_tag_queryreply; MAX_GLOBAL_QUOTA = config->max_global_quota; UNKNOWN_SERVER_NICENESS = config->unknown_server_time_limit; - USEFUL_SERVER_TOP_TIMEOUT = RTT_MAX_TIMEOUT; - BLACKLIST_PENALTY = USEFUL_SERVER_TOP_TIMEOUT*4; log_set_time_asc(config->log_time_ascii); log_set_time_iso(config->log_time_iso); autr_permit_small_holddown = config->permit_small_holddown; @@ -2771,78 +2805,101 @@ int options_remote_is_address(struct config_file* cfg) return (cfg->control_ifs.first->str[0] != '/'); } -/** see if interface is https, its port number == the https port number */ int -if_is_https(const char* ifname, const char* port, int https_port) +if_listens_on(const char* ifname, int default_port, int port, + struct config_strlist* additional_ports) { + struct config_strlist* s; char* p = strchr(ifname, '@'); - if(!p && atoi(port) == https_port) - return 1; - if(p && atoi(p+1) == https_port) - return 1; + int if_port; + if(p) if_port = atoi(p+1); + else if_port = default_port; + + if(port && if_port == port) return 1; + + for(s = additional_ports; s; s = s->next) { + if(if_port == atoi(s->str)) return 1; + } return 0; } -/** see if config contains https turned on */ -int cfg_has_https(struct config_file* cfg) +int +if_is_ssl(const char* ifname, int default_port, int ssl_port, + struct config_strlist* tls_additional_port) { - int i; - char portbuf[32]; - snprintf(portbuf, sizeof(portbuf), "%d", cfg->port); - for(i = 0; i<cfg->num_ifs; i++) { - if(if_is_https(cfg->ifs[i], portbuf, cfg->https_port)) - return 1; - } - return 0; + return if_listens_on(ifname, default_port, ssl_port, + tls_additional_port); } -/** see if interface is PROXYv2, its port number == the proxy port number */ int -if_is_pp2(const char* ifname, const char* port, +if_is_pp2(const char* ifname, int default_port, struct config_strlist* proxy_protocol_port) { - struct config_strlist* s; - char* p = strchr(ifname, '@'); - for(s = proxy_protocol_port; s; s = s->next) { - if(p && atoi(p+1) == atoi(s->str)) - return 1; - if(!p && atoi(port) == atoi(s->str)) - return 1; - } - return 0; + return if_listens_on(ifname, default_port, 0, proxy_protocol_port); +} + +int +if_is_https(const char* ifname, int default_port, int https_port) +{ + return if_listens_on(ifname, default_port, https_port, NULL); } -/** see if interface is DNSCRYPT, its port number == the dnscrypt port number */ int -if_is_dnscrypt(const char* ifname, const char* port, int dnscrypt_port) +if_is_dnscrypt(const char* ifname, int default_port, int dnscrypt_port) { #ifdef USE_DNSCRYPT - return ((strchr(ifname, '@') && - atoi(strchr(ifname, '@')+1) == dnscrypt_port) || - (!strchr(ifname, '@') && atoi(port) == dnscrypt_port)); + return if_listens_on(ifname, default_port, dnscrypt_port, NULL); #else (void)ifname; - (void)port; + (void)default_port; (void)dnscrypt_port; return 0; #endif } -/** see if interface is quic, its port number == the quic port number */ +size_t +getmem_str(char* str) +{ + if(!str) return 0; + return strlen(str)+1; +} + int -if_is_quic(const char* ifname, const char* port, int quic_port) +if_is_quic(const char* ifname, int default_port, int quic_port) { -#ifndef HAVE_NGTCP2 +#ifdef HAVE_NGTCP2 + return if_listens_on(ifname, default_port, quic_port, NULL); +#else (void)ifname; - (void)port; + (void)default_port; (void)quic_port; return 0; +#endif +} + +int +cfg_has_https(struct config_file* cfg) +{ + int i; + for(i = 0; i<cfg->num_ifs; i++) { + if(if_is_https(cfg->ifs[i], cfg->port, cfg->https_port)) + return 1; + } + return 0; +} + +int +cfg_has_quic(struct config_file* cfg) +{ +#ifdef HAVE_NGTCP2 + int i; + for(i = 0; i<cfg->num_ifs; i++) { + if(if_is_quic(cfg->ifs[i], cfg->port, cfg->quic_port)) + return 1; + } + return 0; #else - char* p = strchr(ifname, '@'); - if(!p && atoi(port) == quic_port) - return 1; - if(p && atoi(p+1) == quic_port) - return 1; + (void)cfg; return 0; #endif } diff --git a/util/config_file.h b/util/config_file.h index 2969f8433963..89bbc1c7d856 100644 --- a/util/config_file.h +++ b/util/config_file.h @@ -54,6 +54,9 @@ struct sock_list; struct ub_packed_rrset_key; struct regional; +/** Default value for PROBE_MAXRTO */ +#define PROBE_MAXRTO_DEFAULT 12000 + /** List head for strlist processing, used for append operation. */ struct config_strlist_head { /** first in list of text items */ @@ -435,8 +438,6 @@ struct config_file { /** serve expired entries only after trying to update the entries and this * timeout (in milliseconds) is reached */ int serve_expired_client_timeout; - /** serve EDE code 3 - Stale Answer (RFC8914) for expired entries */ - int ede_serve_expired; /** serve original TTLs rather than decrementing ones */ int serve_original_ttl; /** nsec3 maximum iterations per key size, string */ @@ -738,22 +739,30 @@ struct config_file { #ifdef USE_REDIS /** redis server's IP address or host name */ char* redis_server_host; + char* redis_replica_server_host; /** redis server's TCP port */ int redis_server_port; + int redis_replica_server_port; /** redis server's unix path. Or "", NULL if unused */ char* redis_server_path; + char* redis_replica_server_path; /** redis server's AUTH password. Or "", NULL if unused */ char* redis_server_password; + char* redis_replica_server_password; /** timeout (in ms) for communication with the redis server */ int redis_timeout; + int redis_replica_timeout; /** timeout (in ms) for redis commands */ int redis_command_timeout; + int redis_replica_command_timeout; /** timeout (in ms) for redis connection set up */ int redis_connect_timeout; + int redis_replica_connect_timeout; /** set timeout on redis records based on DNS response ttl */ int redis_expire_records; /** set the redis logical database upon connection */ int redis_logical_db; + int redis_replica_logical_db; #endif #endif /** Downstream DNS Cookies */ @@ -773,6 +782,10 @@ struct config_file { #endif /** respond with Extended DNS Errors (RFC8914) */ int ede; + /** serve EDE code 3 - Stale Answer (RFC8914) for expired entries */ + int ede_serve_expired; + /** send DNS Error Reports to upstream reporting agent (RFC9567) */ + int dns_error_reporting; /** limit on NS RRs in RRset for the iterator scrubber. */ size_t iter_scrub_ns; /** limit on CNAME, DNAME RRs in answer for the iterator scrubber. */ @@ -976,6 +989,10 @@ void config_delete(struct config_file* config); */ void config_apply(struct config_file* config); +/** Apply the relevant changes that rely upon RTT_MAX_TIMEOUT; + * exported for unit test */ +int config_apply_max_rtt(int max_rtt); + /** * Find username, sets cfg_uid and cfg_gid. * @param config: the config structure. @@ -1395,8 +1412,39 @@ void w_config_adjust_directory(struct config_file* cfg); /** debug option for unit tests. */ extern int fake_dsa, fake_sha1; -/** see if interface is https, its port number == the https port number */ -int if_is_https(const char* ifname, const char* port, int https_port); +/** Return true if interface will listen to specific port(s). + * @param ifname: the interface as configured in the configuration file. + * @param default_port: the default port to use as the interface port if ifname + * does not include a port via the '@' notation. + * @param port: port to check for, if 0 it will not be checked. + * @param additional_ports: additional configured ports, if any (nonNULL) to + * be checked against. + * @return true if one of (port, additional_ports) matches the interface port. + */ +int if_listens_on(const char* ifname, int default_port, int port, + struct config_strlist* additional_ports); + +/** see if interface will listen on https; + * its port number == the https port number */ +int if_is_https(const char* ifname, int default_port, int https_port); + +/** see if interface will listen on ssl; + * its port number == the ssl port number or any of the additional ports */ +int if_is_ssl(const char* ifname, int default_port, int ssl_port, + struct config_strlist* tls_additional_port); + +/** see if interface will listen on PROXYv2; + * its port number == any of the proxy ports number */ +int if_is_pp2(const char* ifname, int default_port, + struct config_strlist* proxy_protocol_port); + +/** see if interface will listen on DNSCRYPT; + * its port number == the dnscrypt port number */ +int if_is_dnscrypt(const char* ifname, int default_port, int dnscrypt_port); + +/** see if interface will listen on quic; + * its port number == the quic port number */ +int if_is_quic(const char* ifname, int default_port, int quic_port); /** * Return true if the config contains settings that enable https. @@ -1405,18 +1453,18 @@ int if_is_https(const char* ifname, const char* port, int https_port); */ int cfg_has_https(struct config_file* cfg); -/** see if interface is PROXYv2, its port number == the proxy port number */ -int if_is_pp2(const char* ifname, const char* port, - struct config_strlist* proxy_protocol_port); - -/** see if interface is DNSCRYPT, its port number == the dnscrypt port number */ -int if_is_dnscrypt(const char* ifname, const char* port, int dnscrypt_port); - -/** see if interface is quic, its port number == the quic port number */ -int if_is_quic(const char* ifname, const char* port, int quic_port); +/** + * Return true if the config contains settings that enable quic. + * @param cfg: config information. + * @return true if quic ports are used for server. + */ +int cfg_has_quic(struct config_file* cfg); #ifdef USE_LINUX_IP_LOCAL_PORT_RANGE #define LINUX_IP_LOCAL_PORT_RANGE_PATH "/proc/sys/net/ipv4/ip_local_port_range" #endif +/** get memory for string */ +size_t getmem_str(char* str); + #endif /* UTIL_CONFIG_FILE_H */ diff --git a/util/configlexer.c b/util/configlexer.c index c452d78fd3a2..d69ad059b3ff 100644 --- a/util/configlexer.c +++ b/util/configlexer.c @@ -354,8 +354,8 @@ static void yynoreturn yy_fatal_error ( const char* msg ); (yy_hold_char) = *yy_cp; \ *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 403 -#define YY_END_OF_BUFFER 404 +#define YY_NUM_RULES 412 +#define YY_END_OF_BUFFER 413 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -363,450 +363,461 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static const flex_int16_t yy_accept[4016] = +static const flex_int16_t yy_accept[4118] = { 0, - 1, 1, 377, 377, 381, 381, 385, 385, 389, 389, - 1, 1, 393, 393, 397, 397, 404, 401, 1, 375, - 375, 402, 2, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 402, 377, 378, 378, - 379, 402, 381, 382, 382, 383, 402, 388, 385, 386, - 386, 387, 402, 389, 390, 390, 391, 402, 400, 376, - 2, 380, 400, 402, 396, 393, 394, 394, 395, 402, - 397, 398, 398, 399, 402, 401, 0, 1, 2, 2, - 2, 2, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 377, 0, 381, 0, 388, 0, - 385, 389, 0, 400, 0, 2, 2, 400, 396, 0, - 393, 397, 0, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 400, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 370, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 140, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 150, 401, 401, 401, 401, 401, - 401, 401, 401, 400, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 122, 401, 401, 369, 401, 401, 401, - 401, 401, 401, 401, 401, 8, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 141, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 155, 401, 401, 401, 400, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 359, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 400, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - - 73, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 277, 401, 14, - 15, 401, 401, 20, 19, 401, 401, 251, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 148, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 249, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 3, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 400, 401, 401, 401, 401, 401, 401, - 401, 401, 346, 401, 401, 401, 345, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 384, 401, 401, 401, 401, 401, 401, 401, 401, - 72, 401, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 76, - 401, 315, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 360, 361, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 77, 401, 401, 149, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 144, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 238, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 22, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 176, 401, 401, 401, - 401, 401, 401, 400, 384, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 120, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 323, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 16, 401, 401, 401, 401, 401, 401, 401, - 401, 204, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 175, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 119, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 37, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 38, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 74, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 147, 401, 401, 401, - 400, 401, 401, 401, 401, 401, 401, 139, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 75, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 281, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 205, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 62, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 58, 59, 401, 301, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 67, - 401, 68, 401, 401, 401, 401, 401, 401, 123, 401, - 124, 401, 401, 401, 401, 401, 121, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 7, 401, 401, 401, 401, 401, 400, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 266, 401, 401, 401, 401, 401, 401, 179, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 282, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 51, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 63, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 229, 401, 228, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 17, 18, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 78, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 237, 401, - 401, 401, 401, 401, 401, 401, 126, 401, 125, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 218, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 156, 401, 257, 401, 401, - 401, 400, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 114, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 100, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 250, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 105, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 71, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 222, 223, - 401, 401, 401, 401, 317, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 6, 401, 401, 401, 401, 401, 401, 401, - 336, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 321, 401, 401, 401, 401, 401, 401, - 401, 347, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 48, 401, 401, - 401, 401, 401, 50, 401, 401, 401, 101, 401, 401, - 401, 401, 401, 60, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 400, 401, 214, - 401, 401, 401, 151, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 242, 401, - 401, 215, 401, 401, 401, 401, 401, 262, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 61, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 153, 132, 401, 133, 401, 401, 401, 401, 131, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 172, 401, 401, 56, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 299, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 216, 401, 401, - 401, 401, 401, 227, 219, 401, 226, 401, 401, 221, - 401, 401, 401, 401, 401, 401, 401, 261, 401, 401, - 401, 401, 401, 401, 265, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 118, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 145, 401, 401, 401, 401, 401, 401, 401, 401, 69, - - 401, 401, 401, 401, 31, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 21, 401, 401, - 401, 401, 401, 401, 401, 32, 41, 401, 184, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 212, 401, 401, 400, 401, - 401, 401, 401, 364, 401, 401, 86, 401, 89, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 365, - 401, 401, 401, 401, 401, 401, 401, 401, 325, 401, - 401, 401, 401, 278, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 134, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 171, 401, 52, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 272, 401, 401, 401, 401, - 401, 401, 401, 401, 340, 401, 401, 401, 401, 401, - 372, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 178, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 334, 401, 401, 401, 401, 248, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 354, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 197, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 127, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 191, 401, 206, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 400, 401, 159, 401, 401, 401, 401, - 401, 401, 401, 401, 113, 401, 401, 401, 401, 240, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 263, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 290, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 152, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 195, - 401, 401, 401, 401, 401, 401, 401, 90, 401, 91, - 401, 401, 401, 401, 401, 275, 401, 401, 401, 401, - 401, 70, 343, 401, 401, 401, 401, 401, 401, 99, - 207, 401, 230, 401, 267, 401, 401, 220, 318, 401, - 401, 401, 401, 401, 313, 401, 401, 401, 82, 401, - - 209, 401, 401, 401, 401, 401, 401, 9, 401, 401, - 401, 401, 401, 117, 401, 401, 401, 401, 401, 401, - 305, 401, 401, 401, 401, 401, 401, 401, 401, 239, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 400, 401, - 401, 401, 401, 194, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 196, 256, - 180, 401, 324, 401, 401, 401, 401, 401, 289, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 252, 401, 401, 401, 401, 401, 401, 316, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 177, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 344, 401, 401, 208, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 81, 83, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 116, 401, 401, 401, - 401, 401, 401, 303, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 320, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 244, 401, 39, - 33, 35, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 40, 401, 34, 36, 401, - 42, 401, 401, 401, 401, 401, 401, 401, 112, 401, - 190, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 400, 401, 401, 401, 401, 401, 401, 401, 401, 348, - 401, 401, 401, 401, 401, 246, 243, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 80, 401, - 401, 401, 154, 401, 135, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 173, 53, 401, - 401, 401, 392, 13, 401, 401, 401, 401, 401, 401, - 401, 160, 401, 401, 401, 401, 401, 401, 401, 401, - 338, 401, 341, 401, 373, 401, 401, 401, 401, 401, - 374, 401, 401, 401, 401, 401, 401, 401, 12, 401, - 401, 23, 401, 401, 401, 401, 401, 401, 401, 309, - 401, 401, 401, 401, 358, 401, 401, 401, 401, 322, - - 401, 401, 401, 401, 84, 401, 254, 401, 401, 401, - 401, 401, 245, 401, 401, 401, 401, 79, 401, 401, - 401, 401, 401, 401, 24, 401, 401, 49, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 189, 188, 401, 401, 401, 401, 392, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 247, 241, - 401, 401, 264, 401, 401, 326, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 202, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 92, 401, 401, 401, 401, - 401, 401, 401, 401, 304, 401, 401, 401, 401, 225, - 401, 401, 401, 401, 401, 401, 253, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 311, 401, 401, - 401, 401, 401, 350, 401, 352, 351, 186, 401, 401, - 401, 85, 401, 401, 401, 401, 198, 401, 401, 401, - 401, 401, 128, 130, 129, 401, 401, 401, 26, 401, - 401, 181, 401, 183, 401, 231, 401, 401, 401, 401, - 187, 401, 401, 258, 401, 401, 401, 401, 268, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 162, 366, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 297, 401, 401, 280, 401, 401, 401, 401, 401, 401, - 401, 367, 401, 28, 401, 319, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 97, 232, 401, 401, 274, - 401, 401, 401, 302, 401, 342, 401, 224, 401, 401, - 314, 401, 401, 401, 312, 64, 401, 401, 401, 401, - 401, 401, 401, 4, 401, 401, 401, 401, 401, 401, - 401, 143, 401, 161, 401, 401, 401, 203, 30, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 271, 43, 44, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 327, 401, 401, 401, 401, 401, 401, 401, - 288, 401, 401, 401, 401, 401, 401, 401, 401, 235, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 96, 95, 401, 401, - 65, 401, 401, 300, 308, 401, 276, 401, 401, 401, - 401, 401, 11, 401, 401, 401, 401, 371, 401, 401, - 401, 401, 401, 401, 401, 142, 401, 401, 401, 401, - 401, 401, 233, 102, 401, 401, 46, 401, 401, 401, - - 401, 401, 401, 401, 401, 193, 401, 259, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 164, 401, 401, - 401, 401, 279, 401, 401, 401, 401, 401, 287, 401, - 401, 401, 401, 157, 401, 401, 401, 136, 138, 137, - 401, 401, 401, 104, 109, 103, 401, 401, 174, 401, - 401, 401, 401, 93, 401, 273, 310, 401, 401, 401, - 401, 401, 401, 10, 401, 401, 401, 401, 401, 306, - 401, 401, 357, 401, 401, 401, 401, 401, 401, 401, - 401, 363, 45, 401, 401, 401, 401, 401, 192, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 110, 108, 401, - 401, 401, 57, 401, 401, 94, 401, 339, 401, 401, - 401, 401, 25, 401, 401, 401, 401, 401, 217, 401, - 401, 355, 356, 353, 401, 401, 401, 401, 234, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 213, - 401, 401, 182, 87, 88, 401, 401, 401, 401, 401, - 401, 328, 401, 401, 401, 401, 401, 401, 401, 284, - 401, 401, 283, 158, 401, 401, 107, 401, 106, 54, - 401, 401, 165, 166, 169, 170, 167, 168, 98, 337, - - 401, 401, 307, 146, 401, 401, 401, 401, 27, 401, - 185, 401, 401, 401, 401, 401, 211, 401, 270, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 200, 199, 236, 47, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 335, 401, 401, 401, 401, 115, 401, 401, - 269, 401, 401, 298, 332, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 368, 401, 111, 55, - - 66, 5, 401, 401, 255, 401, 401, 401, 401, 333, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 285, - 29, 401, 401, 401, 260, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 286, 401, 401, 401, 401, - 163, 401, 401, 401, 401, 401, 401, 401, 401, 201, - 401, 210, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 329, 401, 401, 401, 401, 401, 401, - 401, 401, 401, 401, 401, 401, 401, 401, 401, 401, - 401, 401, 362, 349, 401, 401, 293, 401, 401, 401, - 401, 401, 330, 401, 401, 401, 401, 401, 401, 331, - - 401, 401, 401, 291, 401, 294, 295, 401, 401, 401, - 401, 401, 292, 296, 0 + 1, 1, 386, 386, 390, 390, 394, 394, 398, 398, + 1, 1, 402, 402, 406, 406, 413, 410, 1, 384, + 384, 411, 2, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 411, 386, 387, 387, + 388, 411, 390, 391, 391, 392, 411, 397, 394, 395, + 395, 396, 411, 398, 399, 399, 400, 411, 409, 385, + 2, 389, 409, 411, 405, 402, 403, 403, 404, 411, + 406, 407, 407, 408, 411, 410, 0, 1, 2, 2, + 2, 2, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 386, 0, 390, 0, 397, 0, + 394, 398, 0, 409, 0, 2, 2, 409, 405, 0, + 402, 406, 0, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 409, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 378, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 140, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 150, 410, 410, 410, 410, + 410, 410, 410, 410, 409, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 122, 410, 410, 377, 410, + 410, 410, 410, 410, 410, 410, 410, 8, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 141, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 155, 410, 410, 410, 409, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 367, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 409, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 73, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 277, 410, 14, 15, 410, 410, 20, 19, 410, + 410, 251, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 148, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 249, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 3, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 410, 410, 410, 409, 410, + 410, 410, 410, 410, 410, 410, 410, 346, 410, 410, + 410, 345, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 393, 410, 410, + 410, 410, 410, 410, 410, 410, 72, 410, 410, 410, + + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 76, 410, 315, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 368, 369, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 77, 410, 410, 149, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 144, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 238, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 22, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 176, 410, 410, 410, 410, 410, 410, + 409, 393, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 120, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 323, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 16, 410, 410, 410, 410, 410, 410, 410, 410, 204, + + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 175, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 119, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 37, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 38, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 74, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 147, 410, 410, 410, 409, + 410, 410, 410, 410, 410, 410, 139, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 75, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 281, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 205, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 62, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 58, 59, 410, 301, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 67, 410, 68, 410, 410, 410, 410, 410, 410, 123, + 410, 124, 410, 410, 410, 410, 410, 121, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 7, 410, 410, 410, 410, 410, 409, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 266, 410, 410, 410, 410, 410, 410, 179, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 282, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 51, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 63, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 229, 410, + 228, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 17, 18, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 410, 410, 78, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 237, 410, 410, 410, 410, 410, 410, 410, 126, + 410, 125, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 218, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 156, 410, + 257, 410, 410, 410, 409, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 114, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 100, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 250, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 105, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 71, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 222, 223, 410, 410, 410, 410, 317, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 6, 410, 410, 410, + 410, 410, 410, 410, 336, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 321, 410, + 410, 410, 410, 410, 410, 410, 347, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 48, 410, 410, 410, 410, 410, 50, 410, + + 410, 410, 101, 410, 410, 410, 410, 410, 60, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 409, 410, 214, 410, 410, 410, 151, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 242, 410, 410, 215, 410, 410, 410, + 410, 410, 410, 262, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 61, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 153, 132, 410, + 133, 410, 410, 410, 410, 131, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 410, 410, 172, 410, 410, + 56, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 299, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 216, 410, 410, 410, 410, 410, 227, + 219, 410, 226, 410, 410, 221, 410, 410, 410, 410, + 410, 410, 410, 261, 410, 410, 410, 410, 410, 410, + 265, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 118, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 410, 410, 145, 410, 410, + 410, 410, 410, 410, 410, 410, 69, 410, 410, 410, + 410, 31, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 21, 410, 410, 410, 410, 410, + 410, 410, 32, 41, 410, 184, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 212, 410, 410, 409, 410, 410, 410, 410, + 372, 410, 410, 86, 410, 89, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 373, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 325, 410, 410, 410, + + 410, 278, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 134, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 171, 410, 52, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 272, 410, 410, 410, 410, 410, 410, + 410, 410, 340, 410, 410, 410, 410, 410, 381, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 178, 410, 410, + + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 334, 410, 410, 410, 410, 248, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 358, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 197, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 127, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 191, 410, 206, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 409, 410, 159, 410, 410, 410, 410, 410, + + 410, 410, 410, 113, 410, 410, 410, 410, 240, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 263, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 290, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 152, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 195, + 410, 410, 410, 410, 410, 410, 410, 90, 410, 91, + 410, 410, 410, 410, 410, 275, 410, 410, 410, 410, + 410, 70, 343, 410, 410, 410, 410, 410, 410, 99, + + 207, 410, 230, 410, 267, 410, 410, 220, 318, 410, + 410, 410, 410, 410, 313, 410, 410, 410, 82, 410, + 209, 410, 410, 410, 410, 410, 410, 9, 410, 410, + 410, 410, 410, 117, 410, 410, 410, 410, 410, 410, + 305, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 239, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 409, 410, 410, 410, 410, 194, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 196, 256, 180, 410, 410, 324, 410, 410, + 410, 410, 410, 289, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 252, 410, 410, 410, + 410, 410, 410, 316, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 177, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 344, 410, 410, 208, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 81, + 83, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 116, 410, 410, 410, 410, 410, 410, 303, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 320, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 244, 410, 39, 33, + 35, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 40, 410, 34, 36, 410, 42, + 410, 410, 410, 410, 410, 410, 410, 112, 410, 190, + + 410, 410, 410, 410, 410, 410, 410, 410, 410, 409, + 410, 410, 410, 410, 410, 410, 410, 410, 348, 410, + 410, 410, 410, 410, 246, 243, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 80, 410, + 410, 410, 154, 410, 135, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 173, 53, 410, + 410, 410, 401, 13, 410, 410, 410, 410, 410, 410, + 410, 160, 410, 410, 410, 410, 410, 410, 410, 410, + 338, 410, 341, 410, 382, 410, 410, 410, 410, 410, + + 383, 410, 410, 410, 410, 410, 410, 410, 12, 410, + 410, 23, 410, 410, 410, 410, 410, 410, 410, 309, + 410, 410, 410, 410, 365, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 322, 410, 410, 410, 410, 84, + 410, 254, 410, 410, 410, 410, 410, 245, 410, 410, + 410, 410, 79, 410, 410, 410, 410, 410, 410, 24, + 410, 410, 49, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 189, 188, 410, 410, 410, + 410, 401, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 247, 241, 410, 410, 410, 264, 410, + + 410, 326, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 202, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 92, 410, 410, 410, 410, 410, 410, 410, 410, + 304, 410, 410, 410, 410, 225, 410, 410, 410, 410, + 410, 410, 253, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 311, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 350, 410, 354, 352, 186, 410, + 410, 410, 85, 410, 410, 410, 410, 198, 410, 410, + + 410, 410, 410, 128, 130, 129, 410, 410, 410, 26, + 410, 410, 181, 410, 183, 410, 231, 410, 410, 410, + 410, 187, 410, 410, 258, 410, 410, 410, 410, 268, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 162, + 374, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 297, 410, 410, 280, 410, 410, 410, 410, + 410, 410, 410, 375, 410, 28, 410, 319, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 97, 232, 410, + 410, 274, 410, 410, 410, 302, 410, 342, 410, 224, + + 410, 410, 314, 410, 410, 410, 312, 64, 410, 410, + 410, 410, 410, 410, 410, 4, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 143, 410, + 161, 410, 410, 410, 203, 30, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 271, 43, 44, + 410, 410, 410, 410, 410, 410, 410, 379, 410, 410, + 327, 410, 410, 410, 410, 410, 410, 410, 288, 410, + 410, 410, 410, 410, 410, 410, 410, 235, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 96, 95, 410, 410, 65, 410, + 410, 300, 308, 410, 276, 410, 410, 410, 410, 410, + 11, 410, 410, 410, 410, 380, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 142, 410, + 410, 410, 410, 410, 410, 233, 102, 410, 410, 46, + 410, 410, 410, 410, 410, 410, 410, 410, 193, 410, + 259, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 164, 410, 410, 410, 410, 279, 410, 410, 410, 410, + 410, 287, 410, 410, 410, 410, 157, 410, 410, 410, + 136, 138, 137, 410, 410, 410, 104, 109, 103, 410, + + 410, 174, 410, 410, 410, 410, 93, 410, 273, 310, + 410, 410, 410, 410, 410, 410, 10, 410, 410, 410, + 410, 410, 306, 410, 410, 364, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 371, + 45, 410, 410, 410, 410, 410, 192, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 110, 108, 410, 410, 410, + 57, 410, 410, 94, 410, 339, 410, 410, 410, 410, + 25, 410, 410, 410, 410, 410, 217, 410, 410, 360, + + 362, 410, 410, 410, 410, 410, 359, 356, 410, 410, + 410, 410, 234, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 213, 410, 410, 182, 87, 88, 410, + 410, 410, 410, 410, 410, 328, 410, 410, 410, 410, + 410, 410, 410, 284, 410, 410, 283, 158, 410, 410, + 107, 410, 106, 54, 410, 410, 165, 166, 169, 170, + 167, 168, 98, 337, 410, 410, 307, 410, 410, 410, + 410, 410, 410, 146, 410, 410, 410, 410, 27, 410, + 185, 410, 410, 410, 410, 410, 211, 410, 270, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 200, + 199, 236, 47, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 335, + 410, 410, 410, 366, 410, 410, 410, 410, 410, 410, + 410, 115, 410, 410, 269, 410, 410, 298, 332, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 376, 410, 111, 55, 66, 5, 410, 410, 351, 410, + 355, 353, 410, 410, 255, 410, 410, 410, 410, 333, + + 410, 410, 410, 410, 410, 410, 410, 410, 410, 285, + 29, 410, 410, 410, 410, 410, 410, 260, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 286, 410, + 410, 410, 410, 410, 410, 410, 163, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 201, 410, + 210, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 361, 363, 357, 410, 410, 329, 410, 410, 410, 410, + 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, + 410, 410, 410, 410, 370, 349, 410, 410, 293, 410, + 410, 410, 410, 410, 330, 410, 410, 410, 410, 410, + + 410, 331, 410, 410, 410, 291, 410, 294, 295, 410, + 410, 410, 410, 410, 292, 296, 0 } ; static const YY_CHAR yy_ec[256] = @@ -852,17 +863,17 @@ static const YY_CHAR yy_meta[67] = 1, 1, 1, 1, 1, 1 } ; -static const flex_int16_t yy_base[4034] = +static const flex_int16_t yy_base[4136] = { 0, 0, 0, 64, 67, 70, 72, 78, 84, 89, 92, - 131, 137, 112, 118, 123, 142, 573, 532, 96,11459, - 11459,11459, 160, 185, 116, 183, 229, 132, 175, 173, + 131, 137, 112, 118, 123, 142, 573, 532, 96,11766, + 11766,11766, 160, 185, 116, 183, 229, 132, 175, 173, 278, 50, 66, 120, 230, 268, 159, 325, 226, 377, - 418, 290, 318, 279, 177, 126, 380, 531,11459,11459, - 11459, 95, 469,11459,11459,11459, 181, 464, 493,11459, - 11459,11459, 238, 424,11459,11459,11459, 104, 422,11459, - 394,11459, 167, 350, 380, 402,11459,11459,11459, 405, - 329,11459,11459,11459, 146, 306, 424, 168, 0, 436, + 418, 290, 318, 279, 177, 126, 380, 531,11766,11766, + 11766, 95, 469,11766,11766,11766, 181, 464, 493,11766, + 11766,11766, 238, 424,11766,11766,11766, 104, 422,11766, + 394,11766, 167, 350, 380, 402,11766,11766,11766, 405, + 329,11766,11766,11766, 146, 306, 424, 168, 0, 436, 0, 0, 225, 219, 252, 209, 319, 215, 248, 357, 283, 339, 417, 428, 429, 354, 371, 444, 263, 463, @@ -887,868 +898,890 @@ static const flex_int16_t yy_base[4034] = 1009, 1003, 989, 1004, 1006, 1013, 1015, 1027, 1021, 1018, 1020, 1039, 1026, 1051, 1050, 1052, 1061, 1045, 1049, 1040, - 1056, 1059, 1066, 1064, 1069, 1072, 1078, 1093, 1096, 150, - 1077, 1102, 1105, 1082, 1111, 1107, 1104, 1109, 1119, 1121, - 11459, 1086, 1100, 1116, 1115, 1120, 1145, 1150, 1147, 1155, - 1161, 1134, 1141, 1136, 1156, 1163, 1162, 1167, 1171, 1168, - 1179, 1172, 1183, 1200, 1209, 1196, 1210, 1212, 1199, 1244, - 1204, 1198, 1214, 1289, 1230, 1205, 1238, 1249, 1222, 488, - 1255, 1254, 1278, 1257, 1259, 1285, 1284, 1288, 1273, 1282, - 1312, 1316, 1301, 1321, 1322, 1239, 1319, 1323, 1318, 1332, - 1337, 1354,11459, 1340, 1351, 1367, 1363, 1365, 1372, 1371, - 1384, 1398, 1379, 1395, 1391, 1380, 1400, 1446, 1494, 1389, - - 1410, 1393, 1406, 1412,11459, 1435, 1415, 1543, 1430, 1425, - 1471, 1448, 1472, 1403, 1441, 1462, 1475, 1461, 1474, 1482, - 1466, 1443, 1489, 1534, 1491, 1505, 1506, 1493, 1542, 1544, - 1521, 1533, 1550, 1548, 1527, 1561, 1553, 1569, 1565, 1571, - 1576, 1601, 1577, 1582, 1589, 1591, 1596, 1609, 1588, 1619, - 1623, 1626, 1624, 1614, 1616, 1628, 1629, 1599, 1653, 1698, - 1640, 1650, 1637, 1664, 1654, 1670, 1657, 1677, 1690, 1679, - 1691, 1681, 1686, 1680, 1479, 1705, 1717, 1713, 1728, 1704, - 1730, 1723, 1718, 1720, 1731, 1732, 1760, 1740, 1745, 1748, - 1758, 1768, 1762, 1755, 1772, 1773, 1779, 1782, 1780, 1785, - - 1792, 1801, 1789,11459, 1753, 1814,11459, 1797, 1812, 1804, - 1817, 1806, 1829, 1803, 1810,11459, 1828, 1833, 1816, 1837, - 1843, 1840, 1849, 1850, 1863, 1861, 1855, 1872, 1871, 1867, - 1864, 1876, 1877, 1882, 1884, 1905, 1899, 1892, 1893, 1895, - 1914, 1900, 1920, 1906, 1926, 1912, 1911, 1922, 1962,11459, - 1939, 1944, 1919, 1933, 1948, 1964, 1956, 1973, 1975, 1983, - 1996, 1997, 2003, 2022, 1991, 2004, 2011, 2009, 1999, 2028, - 2010, 2033, 2030, 2038, 2036, 2041, 2025, 2031, 2059, 2057, - 2048, 2055, 2068,11459, 2061, 2072, 2075, 2083, 2088, 2077, - 2090, 2084, 2071, 2095, 2092, 1844, 2109, 2108, 2116, 2096, - - 2117, 2124, 2101, 2114, 2132, 2134, 2119, 2130, 2123, 2127, - 2144, 2135, 2152, 2154, 2140, 2177, 2161, 2138, 2168, 782, - 2180, 2178, 2184, 2185, 2191, 2169, 2171, 2181, 2186, 2194, - 2183, 2195, 2206, 2210, 2200, 2198, 2220, 2211, 2208, 2227, - 2214, 2229, 2225, 2242, 2230, 2219, 2244, 2241, 2237, 2254, - 2267, 2258, 2251, 2285, 2255, 2276, 2257, 2279, 2278, 2281, - 2284, 2292,11459, 2306, 2294, 2290, 2311, 2323, 2310, 2313, - 2325, 2326, 2316, 2312, 2335, 2333, 2339, 2341, 2347, 2354, - 2345, 2350, 2343, 2357, 2353, 2366, 2370, 2371, 2390, 2380, - 2384, 2397, 2373, 2396, 2398, 2394, 2388, 2404, 2414, 2401, - - 2406, 2417, 2409, 2405, 2413, 2429, 2421, 2455, 2430, 2427, - 2444, 2439, 2480, 2432, 2441, 2454, 2446, 2447, 2461, 2468, - 2469, 2488, 2477, 2474, 2493, 2514, 2496, 2503, 2509, 2502, - 2515, 2495, 2513, 2519, 2527, 2520, 2529, 2555, 2530, 2542, - 2538, 2544, 2550, 2533, 2571, 2548, 2567, 2561, 2570, 2573, - 2572, 2566, 2577, 2588, 2589, 2586, 2599, 2603, 2601, 2605, - 2604, 2611, 2626, 2629, 2623, 2616, 2628, 2631, 2636, 2630, - 2640, 2648, 2658, 2664, 2663, 2647, 2672, 2673, 2662, 2674, - 2667, 2668, 2675, 2697, 2698, 2578, 2688, 2709, 2713, 2700, - 2707, 2703, 2719, 2715, 2705, 2505, 2746, 2757, 2733, 2739, - - 11459, 2704, 2692, 2732, 2734, 2731, 2752, 2742, 2745, 2773, - 2775, 2768, 2770, 2753, 2758, 2766, 2812,11459, 2774,11459, - 11459, 777, 2779,11459,11459, 2799, 2782,11459, 2798, 2813, - 2802, 2806, 2823, 2829, 2835, 2826, 2825, 2828, 2840, 2850, - 2887, 2845, 2863, 2852, 2848, 2870, 2856, 2882, 2871, 2877, - 2907, 2895, 2892, 2921, 2925, 2904, 2926, 2913, 2931, 2929, - 2937, 2938, 2940, 2943, 2944, 2935, 2956, 2955, 2958, 2957, - 2960, 2953, 2965, 2963, 2969, 2967, 2990, 2980, 2983, 2987, - 3002, 2994, 3000, 3020,11459, 2996, 3016, 3010, 3006, 3011, - 3014, 3018, 3026, 3037, 3032, 3013, 3036, 3042, 3048, 3038, - - 3041, 3052, 3045, 3051, 3047, 3062, 3057, 3066, 3060, 3077, - 3082, 3067, 3071, 3074, 3069,11459, 3093, 3081, 3079, 3094, - 3095, 3087, 3101, 3113, 3114, 3121, 3120, 3117, 3108, 3127, - 3126, 3161, 3128, 3145, 3144, 3130, 3153, 3140, 3147, 3167, - 11459, 3166, 3175, 3156, 3174, 3160, 3180, 3176, 3189, 3188, - 3191, 3190, 3197, 3194, 3195, 3200, 3100, 3205, 3216, 3215, - 3225, 3221, 3223, 3222, 3237, 3234, 3233, 3226, 3243, 3250, - 3247, 3246, 3248, 3257, 3261, 3249, 3262, 3270, 3288, 3271, - 3292, 3277, 3273, 3297, 3304, 3298, 3284, 3296, 3300, 3301, - 3309, 3306, 3318, 3311, 3299, 3321, 3326, 3319, 3340, 3324, - - 3337, 3347, 3354, 3359, 3341, 3351, 3361, 3336, 3353, 3360, - 3366, 3376,11459, 3367, 3378, 3387,11459, 3383, 3384, 3385, - 3431, 3403, 3423, 3412, 3411, 3421, 3402, 3441, 3417, 3444, - 3435, 3450, 3443, 3465, 3466, 3464, 3479, 3470, 3489, 3469, - 3482, 3474, 3480, 3492, 3484, 3491, 3515, 3497, 3518, 3414, - 3531, 3528, 414, 3534, 3510, 3514, 3517, 3562, 3526, 3546, - 3525, 3544, 3547, 3552, 3559, 3550, 3553, 3558, 3573, 3574, - 3571, 3607, 3599, 3594, 3595, 3589, 3600, 3610, 3611, 3608, - 3597,11459, 3615, 3620, 3622, 3624, 3630, 3635, 3631, 3627, - 11459, 3639, 3644, 3645, 3657, 3638, 3651, 3650, 3662, 3654, - - 3665, 3663, 3656, 3670, 3684, 3686, 3692, 3683, 3690,11459, - 3688,11459, 3685, 3687, 3701, 3691, 3703, 3710, 3705, 3709, - 3715, 3725, 3734, 3736,11459,11459, 3742, 3743, 3729, 3744, - 3726, 3749, 3737, 3762, 3765,11459, 3763, 3754,11459, 3781, - 3768, 3784, 3766, 3771, 3789, 3776, 3786, 3801, 3795, 3770, - 3806, 3805, 3829, 3810, 3836, 3823, 3834, 3821,11459, 3824, - 3837, 3822, 3848, 3849, 3842, 3832, 3850, 3866, 3833,11459, - 3867, 3862, 3868, 3863, 3888, 3757, 3870, 3869, 3883, 3890, - 3881, 3885, 3882, 3889, 3894, 3893, 3908, 3927, 3918, 3919, - 3930, 3928, 3932,11459, 3931, 3920, 3917, 3935, 3934, 3759, - - 3940, 3943, 3948, 3950, 3954, 3966, 3971, 3945, 3977, 3960, - 3972, 3967, 3976, 3990, 3987, 3983, 3989, 3993, 3992, 3995, - 4000, 158, 4003, 3999, 4004, 4011,11459, 4005, 4016, 4028, - 4029, 4035, 4039, 4022, 115, 4027, 4031, 4045, 4048, 4038, - 4055, 4059, 4056, 4065, 4066, 4069, 4063, 4071, 4074, 4083, - 4084, 4067, 4086, 4090, 4092, 4072, 4099, 4108, 4094, 4101, - 11459, 4123, 4110, 4121, 4122, 4112, 4117, 4127, 4118, 4148, - 11459, 4139, 4145, 4136, 4155, 4149, 4158, 4147, 4166, 4159, - 4163, 4168,11459, 4174, 4165, 4175, 4202, 4194, 4186, 4192, - 4188,11459, 4209, 4205, 4211, 4197, 4213, 4208, 4214, 4227, - - 4231, 4201, 4245, 4234, 4226, 4239, 4236, 4204, 4238, 4253, - 4247, 4266, 4269, 4265, 4267, 4270, 4275, 4272, 4283, 4281, - 4276, 4292, 4286, 4278,11459, 4314, 4296, 4302, 4312, 4304, - 4305, 4325, 4323, 4342, 4317, 4319, 4313, 4344, 4372, 4347, - 4343, 4352, 4359, 4365, 4362, 4351, 4375, 4363, 4382, 4392, - 4400, 4389, 4404, 4393, 4406, 4403, 4417, 4408, 4411, 4412, - 4425, 4416, 4440, 4427, 4428, 4422, 4444, 4452, 4453, 4447, - 4449, 4481, 4454, 4443, 4464, 4484, 4476,11459, 4471, 4473, - 4485, 4486, 4498, 4466, 4469, 4521, 4493, 4496, 4500, 4520, - 4508, 4513, 4524, 4532, 4523, 4525, 4535, 4548, 4545, 4527, - - 4547, 4550, 4553, 4556, 4551, 4554, 4566, 4565, 4562, 4579, - 4571, 4595, 4591, 4597,11459, 4598, 4600, 4583, 4594, 4604, - 4587, 4608, 4611, 4610, 4619, 4620, 4622, 4609, 4624, 4628, - 4630, 4632, 4621, 4648, 4647, 4659, 4636,11459, 4655, 4635, - 4651, 4660, 4662, 4668, 4682, 4679, 4666, 4689, 4696, 4693, - 4681, 4695, 4700, 4691,11459, 4710, 4715, 4708, 4709, 4717, - 4720, 4711, 4721, 4719, 4723, 4725,11459, 4728, 4731, 4741, - 4738, 4734, 4739, 4744, 4768, 4758, 4756,11459, 4774, 4759, - 4770, 4772, 4780, 4776, 4775, 4778, 4791, 4797, 4788, 4785, - 4795, 4811, 4802, 4821, 4803, 4822,11459, 4812, 4814, 4819, - - 4850, 4815, 4825, 4836, 4837, 4841, 4847, 4861, 4848, 4868, - 4853,11459, 4877, 4860, 4875, 4871, 4886, 4872, 4874, 4887, - 4880, 4903, 4906, 4892, 4895, 4912, 4896,11459, 4907, 4902, - 4913, 4923, 4922, 4918, 4927, 4930, 4929, 4939, 4933, 4945, - 4947, 4949, 4942, 4960, 4963, 4966, 4957, 4953, 4972, 4974, - 4969, 4980, 4985, 4994, 4986, 4982, 4990, 5016, 5001, 5013, - 5018, 5017, 5004, 4998, 5021, 5029, 5034, 5037, 5035, 5038, - 11459, 5049, 5047, 5043, 5041, 5042, 5053, 5056, 5048, 5072, - 5057, 5080, 5062, 5085, 5078, 5074, 5096, 5102, 5091, 5083, - 5105, 5089, 5094, 5100, 5119, 5107, 5112, 5117, 5120, 5116, - - 5123, 5130, 5127, 5121, 5134, 5133, 5147, 5143, 5146, 5161, - 5144, 5157, 5148, 5150, 5164, 5168, 5171, 5176, 5165, 5177, - 5179, 5181, 5192, 5189, 5199, 5202, 5208, 5214, 5204, 5205, - 5206, 5209,11459,11459, 5237,11459, 5224, 5241, 5203, 5231, - 5245, 5238, 5235, 5244, 5254, 5252, 5242, 5248, 5261, 5264, - 5262, 5272, 5281, 5266, 5277, 5269, 5280, 5297, 5298,11459, - 5284,11459, 5311, 5288, 5305, 5313, 5321, 5299,11459, 5317, - 11459, 5315, 5320, 5307, 5312, 5327,11459, 5330, 5331, 5329, - 5326, 5339, 5350, 5346, 5342, 5345, 5360, 5353, 5373, 5370, - 5366, 5356, 5369, 5378, 5362, 5380, 5385, 5377, 5401, 5398, - - 5410, 5411, 5394, 5416, 5396, 5400, 5409, 5425, 5405, 5426, - 11459, 5434, 5454, 5432, 5437, 5443, 5439, 5442, 5449, 5452, - 5451, 5458, 5459, 5466, 5469, 5453, 5479, 5477, 5485, 5486, - 5489, 5482, 5498, 5487, 5500, 5512, 5513, 5499, 5525, 5516, - 11459, 5508, 5523, 5509, 5514, 5526, 5532,11459, 5537, 5527, - 5544, 5546, 5543, 5548, 5541, 5558, 5562, 5549, 5565, 5559, - 5592, 5569, 5585, 5582, 5588,11459, 5590, 5596, 5575, 5594, - 5603, 5589, 5616, 5625, 5624, 5604, 5632, 5640, 5631, 5626, - 5620, 5622, 5628, 5642, 5647, 5649, 5651, 5652, 5655, 5650, - 5656, 5654, 5659, 5644, 5660, 5670, 5672, 5674, 5675, 5678, - - 5682, 5684, 5676, 5679, 5706, 5711, 5689, 5707,11459, 5703, - 5712, 5705, 5731, 5709, 5727, 5726, 5730, 5745, 5749, 5738, - 11459, 5728, 5732, 5755, 5751, 5761, 5753, 5767, 5740, 5765, - 5775, 5782, 5771, 5790, 5791, 5788,11459, 5799,11459, 5789, - 5795, 5798, 5805, 5806, 5809, 5811, 5832, 5822, 5839, 5827, - 5823, 5838, 5828, 5846, 5841, 5831, 5848, 5855, 5860, 5854, - 5858, 5879, 5833, 5880, 5866, 5883, 5885, 5875, 5873, 5878, - 5884, 5881, 5899, 5904, 5902,11459,11459, 5903, 5915, 5916, - 5918, 5911, 5923, 5934, 5936, 5940, 5942, 5943, 5948, 5957, - 5947, 5950, 5954, 5987,11459, 5974, 5975, 5964, 5984, 5979, - - 5973, 5976, 5920, 6000, 5991, 5983, 6009, 5999,11459, 5992, - 6002, 6011, 6013, 6015, 6032, 6036,11459, 6026,11459, 6018, - 6024, 6027, 6039, 6045, 6021, 6031, 6051, 6052, 6042, 6053, - 6075, 6081, 6086, 6079, 6071, 6085, 6068, 6072, 6070, 6091, - 6080, 6105, 6092, 6094, 6104,11459, 6101, 6106, 6120, 6098, - 6107, 6130, 6131, 6129, 6116,11459, 6141,11459, 6134, 6133, - 6137, 6147, 6158, 6148, 6151, 6164, 6160, 6150, 6175, 6167, - 6177, 6171, 6182, 6178, 6185, 6168,11459, 6174, 6172, 6218, - 6202, 6203, 6216, 6224, 6223, 6205, 6227,11459, 6228, 6236, - 6219, 6229, 6240, 6237, 6230, 6245, 6241, 6239, 6248, 6255, - - 6258, 6257, 6272, 6269, 6267, 6265, 6282, 6283, 6286, 6271, - 6307, 6296, 6275, 6293, 6316, 6300,11459, 6309, 6305, 6310, - 6314, 6306, 6336, 6328, 6339, 6331, 6345, 6327, 6349, 6358, - 6341, 6343, 6352, 6350, 6356, 6366, 6372,11459, 6383, 6363, - 6385, 6361, 6386, 6377, 6367, 6393, 6397, 6378, 6401, 6403, - 6399, 6394, 6402, 6411, 6417, 6422, 6436, 6434, 6412, 6433, - 6430, 6440, 6435, 6438, 6445, 6459,11459, 6471, 6442, 6461, - 6466, 6470, 6469, 6475, 6478, 6472, 6480, 6482, 6479, 6489, - 6486, 6503, 6490, 6493, 6517, 6522, 6523, 6505,11459,11459, - 6524, 6508, 6520, 6526,11459, 6527, 6513, 6543, 6537, 6538, - - 6532, 6541, 6546, 6545, 6547, 6560, 6568, 6552, 6570, 6569, - 6554, 6572,11459, 6581, 6585, 6591, 6582, 6576, 6596, 6598, - 11459, 6587, 6597, 6601, 6608, 6607, 6604, 6610, 6617, 6618, - 6599, 6629, 6623, 6625, 6638, 6643, 6622, 6627, 6646, 6660, - 6633, 6649, 6657,11459, 6652, 6640, 6666, 6675, 6659, 6663, - 6679,11459, 6673, 6691, 6680, 6690, 6688, 6701, 6702, 6699, - 6709, 6705, 6706, 6717, 6715, 6708, 6719, 6721, 6723, 6742, - 6733, 6730, 6744, 6740, 6755, 6758, 6752,11459, 6754, 6773, - 6767, 6769, 6764,11459, 6765, 6793, 6778,11459, 6780, 6771, - 6772, 6783, 6807,11459, 6791, 6802, 6796, 6811, 6788, 6814, - - 6799, 6822, 6804, 6820, 6827, 6809, 6817, 6838, 6830,11459, - 6833, 6831, 6846,11459, 6832, 6853, 6860, 6862, 6865, 6863, - 6858, 6852, 6848, 6876, 6875, 6869, 6878, 6873,11459, 6886, - 6904,11459, 6894, 6902, 6889, 6895, 6911,11459, 6903, 6905, - 6893, 6914, 6918, 6921, 6923, 6916, 6935, 6920, 6942, 6931, - 6933, 6941, 6953, 6954, 6961, 6945, 6955, 6947, 6956,11459, - 6984, 6948, 6962, 6968, 6967, 6972, 6992, 6990, 6982, 7000, - 6993,11459,11459, 7007,11459, 7010, 6999, 7008, 7009,11459, - 7016, 7027, 7021, 7022, 7017, 7036, 7032, 7044, 7029, 7053, - 7049,11459, 7055, 7059,11459, 7052, 7056, 7066, 7058, 7063, - - 7042, 7061, 7077, 7091, 7074, 7082, 7084, 7083, 7101, 7080, - 7103, 7099, 7120, 7108, 7140,11459, 7097, 7111, 7124, 7129, - 7127, 7128, 7147, 7144, 7151, 7137, 7133,11459, 7157, 7163, - 7164, 7161, 7174,11459,11459, 7176,11459, 7169, 7186,11459, - 7171, 7192, 7178, 7184, 7180, 7207, 7196,11459, 7202, 7201, - 7206, 7191, 7220, 7228,11459, 7227, 7231, 7219, 7221, 7218, - 7240, 7244, 7243, 7241, 7274, 7252,11459, 7254, 7248, 7265, - 7251, 7271, 7275, 7267, 7264, 7266, 7280, 7288, 7293, 7300, - 7278, 7302, 7298, 7303, 7304, 7307, 7309, 7312, 7313, 7301, - 11459, 7320, 7340, 7330, 7317, 7355, 7341, 7333, 7344,11459, - - 7345, 7350, 7359, 7361,11459, 7357, 7367, 7354, 7373, 7374, - 7377, 7378, 7382, 7381, 7385, 7388, 7402,11459, 7401, 7404, - 7390, 7415, 7419, 7409, 7414,11459,11459, 7429,11459, 7433, - 7426, 7423, 7434, 7430, 7445, 7444, 7458, 7463, 7446, 7450, - 7466, 7473, 7461, 7453, 7472,11459, 7479, 7327, 7462, 7507, - 7488, 7491, 7500,11459, 7496, 7489,11459, 7490,11459, 7485, - 7495, 7487, 7523, 7512, 7520, 7525, 7516, 7514, 7527,11459, - 7534, 7529, 7537, 7540, 7541, 7546, 7553, 7567,11459, 7559, - 7550, 7562, 7554,11459, 7571, 7573, 7552, 7568, 7564, 7587, - 7581, 7588, 7586, 7598, 7585, 7611, 7612, 7602, 7613, 7609, - - 7594, 7610, 7623, 7605, 7636, 7629, 7630, 7622,11459, 7638, - 7633, 7634, 7639, 7644, 7650, 7645, 7649, 7666, 7660, 7687, - 7675, 7688,11459, 7671,11459, 7676, 7682, 7693, 7690, 7680, - 7695, 7701, 7707, 7691, 7697, 7698, 7716, 7731, 7730, 7733, - 7736, 7723, 7725, 7728, 7743,11459, 7742, 7745, 7734, 7750, - 7770, 7753, 7754, 7759,11459, 7761, 7763, 7765, 7772, 7762, - 11459, 7787, 7794, 7776, 7796, 7780, 7800, 7786, 7799, 7805, - 7808, 7802, 7806, 7797, 7818, 7803, 7834, 7822, 7821,11459, - 7832, 7838, 7831, 7839, 7833, 7847, 7835, 7853, 7854, 7857, - 7866, 7860, 7867,11459, 7861, 7871, 7872, 7859,11459, 7880, - - 7874, 7868, 7877, 7901, 7906, 7894, 7888, 7902, 7904, 7907, - 7899, 7924,11459, 7910, 7903, 7935, 7929, 7926, 7927, 7931, - 7921, 7954, 7948, 7958, 7973,11459, 7968, 7953, 7956, 7962, - 7972, 7971, 7984, 7980, 7981, 8000, 7983,11459, 8007, 8008, - 8010, 7987, 8011, 8021, 7998, 8016, 8026, 8017, 8025, 8020, - 8028, 8047, 8034, 8024, 8053, 8055, 8056, 8049, 8061, 8071, - 8066,11459, 8058,11459, 8059, 8060, 8072, 8076, 8093, 8084, - 8099, 8098, 8103, 8105, 8092,11459, 8097, 8100, 7959, 8108, - 8106, 8109, 8130, 8139,11459, 8134, 8131, 8133, 8137,11459, - 8150, 8151, 8132, 8145, 8143, 8162, 8163, 8167, 8168,11459, - - 8184, 8182, 8181, 8173, 8192, 8179, 8191, 8183, 8198, 8189, - 8202, 8190, 8195, 8206, 8210, 8209, 8215,11459, 8217, 8224, - 8232, 8230, 8233, 8231, 8234, 8219, 8241, 8249, 8242,11459, - 8247, 8236, 8244, 8253, 8261, 8274, 8257, 8276, 8258, 8280, - 8288, 8282, 8291, 8272, 8279, 8293, 8305, 8300, 8295,11459, - 8284, 8308, 8323, 8299, 8302, 8322, 8329,11459, 8325,11459, - 8319, 8326, 8335, 8338, 8342,11459, 8344, 8339, 8356, 8346, - 8363,11459,11459, 8371, 8349, 8365, 8378, 8370, 8380,11459, - 11459, 8382,11459, 8366,11459, 8373, 8392,11459,11459, 8383, - 8368, 8395, 8398, 8397,11459, 8412, 8415, 8401,11459, 8403, - - 11459, 8431, 8407, 8428, 8421, 8411, 8435,11459, 8422, 8443, - 8424, 8438, 8432,11459, 8445, 8444, 8451, 8471, 8456, 8454, - 11459, 8452, 8466, 8467, 8479, 8483, 8468, 8470, 8473,11459, - 8498, 8486, 8500, 8493, 8495, 8494, 8503, 8513, 8509, 8510, - 8516, 8514, 8525, 8527, 8534, 8529, 8533, 8544, 8549, 8553, - 8546, 8555, 8541, 8560, 8561, 8563, 8566, 8569, 8550, 8571, - 8575, 8578, 8584, 8579, 8582, 8603, 8604, 8596, 8612, 8602, - 8606, 8605, 8598, 8610, 8616, 8626, 8620, 8629, 8621, 8623, - 8631, 8639, 8630, 8641, 8650, 8648, 8640, 8667, 8658, 8663, - 8665, 8656, 8657,11459, 8675, 8673, 8681, 8683, 8680, 8682, - - 8701, 8692, 8707, 8708, 8711, 8714, 8709, 8715,11459,11459, - 11459, 8717,11459, 8722, 8719, 8736, 8732, 8738,11459, 8734, - 8739, 8733, 8742, 8748, 8743, 8756, 8765, 8766, 8769, 8770, - 8771,11459, 8773, 8729, 8744, 8779, 8781, 8791,11459, 8793, - 8805, 8789, 8792, 8794, 8804, 8808, 8806, 8809, 8814, 8821, - 8818, 8838, 8819, 8825, 8843, 8835, 8829, 8852,11459, 8844, - 8859, 8865, 8845, 8846, 8851, 8849, 8861, 8872, 8880, 8867, - 8869, 8878, 8870, 8873, 8883, 8896, 8904, 8909, 8910, 8913, - 11459, 8899, 8915,11459, 8908, 8900, 8920, 8902, 8916, 8924, - 8914, 8933, 8930, 8935,11459,11459, 8936, 8937, 8949, 8953, - - 8943, 8948, 8967, 8957, 8959, 8965,11459, 8963, 8972, 8982, - 8985, 8971, 8984,11459, 8990, 8991, 8992, 8973, 8986, 8983, - 9000, 9001, 9020,11459, 9010, 9014, 9028, 9024, 9026, 9017, - 9038, 9034, 9031, 9027, 9030, 9044, 9045,11459, 9035,11459, - 11459,11459, 9059, 9065, 9046, 9075, 9063, 9066, 9067, 9069, - 9072, 9073, 9077, 9090, 9070,11459, 9084,11459,11459, 9093, - 11459, 9108, 9100, 9111, 9107, 9099, 9112, 9120,11459, 9104, - 11459, 9117, 9124, 9135, 9130, 9132, 9131, 9137, 9148, 9141, - 9154, 9158, 9156, 9149, 9151, 9171, 9168, 9177, 9170,11459, - 9185, 9174, 9188, 9172, 9190,11459,11459, 9197, 9178, 9203, - - 9204, 9219, 9201, 9205, 9194, 9227, 9221, 9218, 9231, 9217, - 9224, 9230, 9220, 9232, 9245, 9237, 9243, 9249,11459, 9253, - 9251, 9258,11459, 9250,11459, 9266, 9268, 9269, 9257, 9254, - 9270, 9277, 9289, 9282, 9288, 9304, 9298,11459,11459, 9287, - 9312, 9302,11459,11459, 9301, 9306, 9307, 9317, 9310, 9314, - 9319,11459, 9313, 9315, 9342, 9330, 9341, 9337, 9355, 9339, - 11459, 9344,11459, 9340,11459, 9357, 9356, 9348, 9367, 9379, - 11459, 9362, 9372, 9383, 9376, 9384, 9366, 9375,11459, 9386, - 9385,11459, 9401, 9394, 9400, 9387, 9402, 9409, 9408,11459, - 9414, 9421, 9425, 9419,11459, 9420, 9411, 9433, 9439,11459, - - 9440, 9441, 9444, 9442,11459, 9454,11459, 9435, 9453, 9447, - 9470, 9461,11459, 9436, 9457, 9467, 9474,11459, 9479, 9489, - 9490, 9488, 9480, 9482,11459, 9492, 9478,11459, 9483, 9498, - 9507, 9499, 9497, 9511, 9500, 9510, 9515, 9526, 9531, 9532, - 11459,11459, 9546, 9530, 9537, 9538, 73, 9549, 9524, 9525, - 9534, 9542, 9555, 9567, 9571, 9552, 9564, 9578,11459,11459, - 9580, 9579,11459, 9575, 9582,11459, 9561, 9587, 9588, 9601, - 9594, 9602, 9596, 9604, 9608, 9600, 9611, 9629, 9616, 9614, - 9626,11459, 9642, 9644, 9631, 9636, 9647, 9653, 9661, 9663, - 9665, 9652, 9667, 9656, 9658, 9646, 9671, 9673, 9681, 9677, - - 9692, 9693, 9689, 9690, 9695,11459, 9701, 9706, 9704, 9703, - 9712, 9719, 9716, 9708,11459, 9727, 9731, 9732, 9735,11459, - 9741, 9742, 9746, 9744, 9747, 9748,11459, 9743, 9749, 9750, - 9759, 9770, 9745, 9769, 9766, 9765, 9794,11459, 9774, 9786, - 9783, 9784, 9796,11459, 9788,11459,11459,11459, 9797, 9804, - 9791,11459, 9809, 9806, 9792, 9810,11459, 9816, 9834, 9826, - 9576, 9827,11459,11459,11459, 9813, 9836, 9833,11459, 9825, - 9851,11459, 9837,11459, 9829,11459, 9843, 9852, 9858, 9862, - 11459, 9868, 9853,11459, 9863, 9869, 9877, 9898,11459, 9881, - 9883, 9887, 9879, 9885, 9893, 9884, 9897, 9912,11459,11459, - - 9924, 9918, 9922, 9907, 9910, 9909, 9914, 9926, 9915, 9943, - 11459, 9932, 9946,11459, 9948, 9942, 9951, 9960, 9944, 9949, - 9950,11459, 9962,11459, 9966,11459, 9954, 9959, 9983, 9976, - 9986, 9981, 9979, 9977,10000, 9991, 9989, 9994,10016, 9993, - 10008,10004,10015,10019,10018,11459,11459,10039,10022,11459, - 10027,10040,10047,11459,10029,11459,10048,11459,10035,10042, - 11459,10054,10045,10060,11459,11459,10052,10053,10062, 9973, - 10067,10055,10049,11459,10069,10077,10072,10080,10083,10085, - 10084,11459,10088,11459,10086,10110,10104,11459,11459,10092, - 10095,10108,10116,10111,10105,10123,10113,10118,10119,10149, - - 10128,10122,10136,10157,10153,10159,10145,10161,10162,10166, - 11459,11459,11459,10163,10150,10151,10168,10184,10181,10179, - 10201,10185,11459,10194,10204,10200,10188,10206,10196,10210, - 11459,10208,10198,10192,10209,10218,10219,10223,10215,11459, - 10229,10248,10252,10249,10241,10253,10257,10259,10260,10261, - 10242,10262,10251,10245,10266,10268,11459,11459,10267,10276, - 11459,10274,10277,11459,11459,10280,11459,10283,10284,10289, - 10287,10295,11459,10302,10286,10298,10301,11459,10300,10321, - 10318,10304,10314,10337,10336,11459,10325,10326,10329,10319, - 10345,10353,11459,11459,10333,10355,11459,10359,10357,10352, - - 10373,10363,10361,10371,10378,11459,10367,11459,10370,10386, - 10372,10384,10390,10394,10396,10385,10401,11459,10412,10397, - 10405,10409,11459,10419,10399,10423,10417,10422,11459,10443, - 10431,10450,10452,11459,10433,10456,10442,11459,11459,11459, - 10461,10462,10467,11459,11459,11459,10458,10469,11459,10463, - 10476,10468,10466,11459,10477,11459,11459,10472,10507,10511, - 10491,10513,10493,11459,10510,10508,10502,10498,10509,11459, - 10521,10522,11459,10526,10527,10512,10525,10536,10530,10529, - 10531,11459,11459,10535,10539,10557,10555,10550,11459,10549, - 10568,10566,10569,10572,10574,10579,10580,10583,10563,10588, - - 10584,10605,10609,10591,10594,10598,10599,10595,10618,10610, - 10624,10633,10625,10634,10635,10627,10638,11459,11459,10639, - 10641,10648,11459,10649,10644,11459,10645,11459,10657,10659, - 10664,10667,11459,10673,10674,10677,10678,10661,11459,10670, - 10681,11459,11459,11459,10683,10676,10680,10669,11459,10684, - 10693,10690,10695,10698,10702,10706,10720,10711,10724,11459, - 10712,10728,11459,11459,11459,10725,10714,10731,10717,10736, - 10735,11459,10746,10740,10742,10755,10747,10750,10759,11459, - 10765,10763,11459,11459,10774,10764,11459,10780,11459,11459, - 10758,10769,11459,11459,11459,11459,11459,11459,11459,11459, - - 10783,10791,11459,11459,10787,10797,10803,10804,11459,10809, - 11459,10790,10810,10808,10802,10805,11459,10811,11459,10828, - 10818,10815,10829,10831,10835,10842,10838,10840,10830,10847, - 10839,10856,10845,10861,10874,10855,10868,10882,10865,10885, - 10869,10888,11459,11459,11459,11459,10883,10898,10894,10890, - 10901,10902,10900,10907,10913,10919,10903,10916,10920,10928, - 10932,10914,10927,10943,10930,10940,10946,10948,10938,10953, - 10956,10961,11459,10962,10957,10949,10974,11459,10966,10971, - 11459,10963,10959,11459,11459,10991,10993,10984,10978,11001, - 11005,10988,10990,11004,11007,11006,11459,11010,11459,11459, - - 11459,11459,10995,11015,11459,10999,11025,11011,11032,11459, - 11021,11039,11026,11033,11034,11030,11050,11051,11058,11459, - 11459,11059,11057,11061,11459,11060,11064,11062,11070,11089, - 11076,11087,11088,11082,11100,11459,11098,11094,11104,11095, - 11459,11106,11105,11111,11115,11116,11117,11120,11123,11459, - 11128,11459,11125,11141,11137,11143,11140,11150,11145,11152, - 11155,11161,11167,11459,11157,11164,11162,11177,11189,11188, - 11192,11176,11197,11200,11201,11205,11202,11204,11214,11216, - 11213,11217,11459,11459,11212,11223,11459,11220,11232,11227, - 11230,11250,11459,11253,11239,11241,11254,11256,11263,11459, - - 11261,11265,11264,11459,11262,11459,11459,11269,11276,11280, - 11275,11279,11459,11459,11459,11339,11346,11353,11360,11367, - 11374,11381, 100,11388,11395,11402,11409,11416,11423,11430, - 11437,11444,11451 + 1056, 1059, 1066, 1064, 1069, 1072, 1078, 1093, 1096, 1076, + 150, 1077, 1105, 1108, 1098, 1111, 1107, 1113, 1118, 1119, + 1123,11766, 1103, 1129, 1120, 1146, 1124, 1145, 1130, 1147, + 1134, 1164, 1140, 1144, 1157, 1150, 1167, 1177, 1170, 1181, + 1173, 1184, 1195, 1191, 1200, 1186, 1187, 1206, 1213, 1205, + 1244, 1215, 1207, 1223, 1289, 1238, 1218, 1227, 1257, 1272, + 488, 1243, 1249, 1278, 1270, 1286, 1297, 1273, 1284, 1277, + 1312, 1302, 1325, 1311, 1316, 1313, 1211, 1320, 1327, 1328, + 1334, 1242, 1359,11766, 1330, 1361, 1356, 1363, 1369, 1367, + 1365, 1386, 1399, 1355, 1383, 1390, 1400, 1398, 1447, 1495, + + 1389, 1401, 1397, 1417, 1394,11766, 1434, 1440, 1544, 1428, + 1442, 1419, 1439, 1466, 1436, 1463, 1458, 1467, 1478, 1493, + 1444, 1475, 1488, 1490, 1517, 1545, 1506, 1507, 1522, 1534, + 1535, 1554, 1515, 1551, 1555, 1553, 1570, 1562, 1573, 1524, + 1574, 1577, 1589, 1607, 1590, 1592, 1582, 1595, 1600, 1606, + 1618, 1626, 1609, 1638, 1631, 1624, 1633, 1636, 1644, 1640, + 1668, 1713, 1666, 1655, 1667, 1670, 1669, 1671, 1659, 1480, + 1679, 1682, 1687, 1696, 1701, 1695, 1711, 1705, 1715, 1712, + 1732, 1673, 1736, 1717, 1722, 1729, 1757, 1760, 1766, 1743, + 1749, 1753, 1761, 1776, 1774, 1751, 1778, 1780, 1777, 1797, + + 1789, 1806, 1770, 1794, 1792,11766, 1820, 1822,11766, 1804, + 1818, 1807, 1821, 1808, 1827, 1817, 1831,11766, 1842, 1845, + 1819, 1847, 1851, 1856, 1852, 1858, 1866, 1870, 1859, 1869, + 1878, 1874, 1876, 1890, 1887, 1886, 1907, 1914, 1897, 1915, + 1894, 1898, 1908, 1913, 1917, 1921, 1918, 1935, 1933, 1940, + 1980,11766, 1938, 1934, 1941, 1960, 1947, 1965, 1968, 1971, + 2005, 1962, 2004, 2001, 2003, 2030, 2007, 2024, 2015, 1904, + 2023, 2037, 2021, 2051, 2039, 2041, 2044, 2057, 2036, 2047, + 2056, 2063, 2068, 2062, 2070,11766, 2079, 2066, 2088, 2090, + 1974, 2086, 2085, 2082, 2093, 1976, 2095, 2105, 2104, 2103, + + 2109, 2102, 2125, 2124, 1978, 2127, 2145, 2146, 2130, 2141, + 2134, 2132, 2150, 2152, 2159, 2131, 2169, 2154, 2192, 2167, + 2163, 2164, 782, 2172, 2184, 2193, 2200, 2203, 2183, 2181, + 2194, 2210, 2199, 2190, 2208, 2211, 2217, 2219, 2205, 2221, + 2223, 2227, 2230, 2235, 2240, 2241, 2238, 2243, 2250, 2251, + 2254, 2248, 2259, 2265, 2282, 2249, 2285, 2276, 2283, 2277, + 2286, 2300, 2303, 2304, 2274,11766, 2314, 2312, 2310, 2322, + 2324, 2307, 2331, 2330, 2335, 2327, 2320, 2341, 2329, 2354, + 2344, 2361, 2357, 2353, 2358, 2369, 2355, 2365, 2362, 2381, + 2371, 2392, 2388, 2399, 2413, 2391, 2401, 2409, 2398, 2406, + + 2408, 2418, 2405, 2400, 2425, 2442, 2435, 2419, 2434, 2432, + 2458, 2441, 2440, 2447, 2450, 2488, 2465, 2451, 2467, 2482, + 2452, 2483, 2489, 2494, 2495, 2478, 2490, 2521, 2524, 2503, + 2512, 2530, 2519, 2539, 2522, 2527, 2529, 2534, 2523, 2535, + 2485, 2540, 2549, 2560, 2562, 2563, 2559, 2580, 2569, 2585, + 2568, 2579, 2582, 2572, 2576, 2595, 2596, 2598, 2601, 2608, + 2611, 2612, 2613, 2628, 2620, 2635, 2638, 2623, 2627, 2640, + 2652, 2643, 2655, 2649, 2659, 2667, 2675, 2670, 2657, 2678, + 2682, 2673, 2685, 2679, 2676, 2702, 2704, 2708, 2618, 2716, + 2719, 2723, 2710, 2717, 2715, 2725, 2718, 2712, 2689, 2755, + + 2741, 2753, 2752,11766, 2743, 2739, 2744, 2745, 2769, 2766, + 2742, 2757, 2779, 2781, 2787, 2771, 2770, 2783, 2782, 2791, + 2837,11766, 2788,11766,11766, 777, 2799,11766,11766, 2808, + 2814,11766, 2802, 2821, 2831, 2809, 2841, 2852, 2854, 2850, + 2805, 2848, 2843, 2792, 2890, 2851, 2869, 2866, 2877, 2896, + 2879, 2906, 2880, 2886, 2915, 2901, 2914, 2922, 2945, 2924, + 2933, 2929, 2941, 2947, 2949, 2952, 2957, 2696, 2961, 2938, + 2940, 2960, 2951, 2965, 2974, 2972, 2982, 2979, 2975, 2984, + 2996, 2986, 2988, 2981, 2804, 3009, 2833, 3033,11766, 3011, + 3010, 3015, 3008, 3013, 3019, 3023, 3024, 3050, 3031, 3041, + + 3040, 3049, 3052, 3036, 3056, 3044, 3060, 3051, 3063, 3066, + 3053, 3067, 3072, 3076, 3080, 3073, 3100, 3083, 3079,11766, + 3093, 3087, 3082, 3095, 3103, 3092, 3106, 3112, 3119, 3114, + 3131, 3132, 3122, 3113, 3133, 3139, 3162, 3140, 3146, 3141, + 3151, 3144, 3148, 3158, 3179,11766, 3175, 3184, 3165, 3183, + 3166, 3189, 3171, 3180, 3174, 3185, 3199, 3197, 3215, 3204, + 3206, 3233, 3221, 3217, 3218, 3224, 3223, 3232, 3228, 3226, + 3249, 3239, 3250, 3248, 3253, 3251, 3264, 3259, 3260, 3265, + 3263, 3273, 3246, 3290, 3274, 3299, 3289, 3277, 3307, 3310, + 3304, 3294, 3302, 3318, 3291, 3324, 3332, 3333, 3316, 3320, + + 3329, 3337, 3328, 3336, 3326, 3341, 3352, 3358, 3367, 3351, + 3368, 3369, 3355, 3353, 3371, 3378, 3387,11766, 3365, 3388, + 3404,11766, 3395, 3392, 3390, 3443, 3415, 3422, 3405, 3413, + 3424, 3416, 3453, 3436, 3445, 3426, 3447, 3462, 3451, 3482, + 3481, 3479, 3491, 3483, 3496, 3487, 3500, 3488, 3469, 3492, + 3489, 3512, 3526, 3527, 3530, 3363, 3435, 3536, 414, 3517, + 3515, 3522, 3525, 3570, 3534, 3540, 3542, 3538, 3554, 3561, + 3567, 3560, 3564, 3565, 3581, 3585, 3583, 3591, 3608, 3597, + 3601, 3598, 3602, 3603, 3595, 3611, 3612,11766, 3638, 3631, + 3618, 3639, 3630, 3654, 3645, 3633,11766, 3642, 3646, 3640, + + 3658, 3641, 3665, 3657, 3670, 3660, 3672, 3687, 3671, 3678, + 3684, 3685, 3689, 3679, 3705,11766, 3692,11766, 3710, 3706, + 3703, 3700, 3723, 3714, 3715, 3722, 3711, 3730, 3735, 3738, + 11766,11766, 3739, 3741, 3749, 3747, 3752, 3759, 3751, 3754, + 3764,11766, 3766, 3788,11766, 3791, 3774, 3781, 3776, 3778, + 3775, 3779, 3800, 3794, 3805, 3804, 3806, 3815, 3808, 3802, + 3816, 3835, 3819, 3833, 3830,11766, 3847, 3842, 3831, 3849, + 3851, 3837, 3850, 3861, 3862, 3858,11766, 3876, 3857, 3881, + 3869, 3896, 3868, 3883, 3880, 3899, 3900, 3886, 3893, 3891, + 3903, 3908, 3910, 3920, 3927, 3919, 3929, 3937, 3931, 3945, + + 11766, 3938, 3923, 3922, 3949, 3947, 3953, 3946, 3948, 3954, + 3944, 3958, 3963, 3964, 3972, 3973, 3969, 3976, 3979, 3965, + 4000, 3982, 3996, 4002, 3989, 3993, 3999, 3994, 158, 3995, + 4009, 4014, 3992,11766, 4023, 4021, 4031, 4024, 4038, 4041, + 4027, 115, 4035, 4037, 4044, 4048, 4054, 4040, 4061, 4057, + 4071, 4083, 4064, 4070, 4073, 4081, 4090, 4082, 4079, 4080, + 4091, 4088, 4105, 4098, 4095, 4111, 4108,11766, 4131, 4119, + 4130, 4128, 4118, 4116, 4125, 4135, 4122, 4160,11766, 4144, + 4155, 4145, 4139, 4163, 4146, 4164, 4177, 4162, 4166, 4185, + 11766, 4183, 4190, 4186, 4200, 4191, 4202, 4203, 4201,11766, + + 4199, 4217, 4219, 4211, 4227, 4229, 4225, 4230, 4235, 4221, + 4252, 4238, 4256, 4254, 4249, 4248, 4260, 4265, 4258, 4275, + 4247, 4274, 4279, 4280, 4288, 4285, 4296, 4290, 4293, 4295, + 4316, 4305,11766, 4319, 4312, 4314, 4321, 4313, 4322, 4337, + 4332, 4358, 4343, 4320, 4350, 4356, 4390, 4349, 4353, 4365, + 4355, 4378, 4370, 4369, 4385, 4377, 4383, 4402, 4410, 4360, + 4415, 4428, 4400, 4396, 4423, 4437, 4444, 4442, 4439, 4426, + 4447, 4440, 4438, 4449, 4451, 4464, 4458, 4466, 4455, 4489, + 4472, 4473, 4485, 4490, 4481,11766, 4497, 4479, 4491, 4502, + 4506, 4496, 4510, 4527, 4513, 4517, 4530, 4532, 4523, 4521, + + 4540, 4537, 4546, 4533, 4542, 4549, 4554, 4564, 4544, 4566, + 4570, 4572, 4571, 4578, 4568, 4562, 4569, 4581, 4600, 4588, + 4606, 4604, 4608,11766, 4613, 4612, 4599, 4611, 4619, 4602, + 4623, 4624, 4627, 4607, 4621, 4635, 4641, 4633, 4640, 4655, + 4643, 4666, 4659, 4662, 4670, 4647,11766, 4673, 4660, 4668, + 4674, 4680, 4683, 4669, 4700, 4706, 4707, 4710, 4708, 4696, + 4716, 4717, 4715,11766, 4721, 4723, 4720, 4726, 4734, 4736, + 4727, 4748, 4730, 4740, 4742,11766, 4751, 4747, 4754, 4753, + 4750, 4761, 4771, 4776, 4773, 4774,11766, 4781, 4782, 4790, + 4788, 4787, 4798, 4795, 4799, 4801, 4815, 4812, 4808, 4803, + + 4822, 4820, 4824, 4829, 4831,11766, 4834, 4830, 4828, 4867, + 4846, 4848, 4860, 4862, 4858, 4859, 4863, 4887, 4873, 4875, + 4884,11766, 4888, 4890, 4899, 4896, 4918, 4893, 4901, 4911, + 4905, 4916, 4919, 4913, 4915, 4936, 4930,11766, 4933, 4926, + 4934, 4948, 4951, 4946, 4940, 4889, 4953, 4954, 4966, 4969, + 4957, 4973, 4968, 4984, 4991, 4996, 4976, 4990, 4997, 4986, + 4999, 5005, 5012, 5010, 5016, 5021, 5014, 5025, 5024, 5029, + 5040, 5039, 5026, 5023, 5050, 5052, 5063, 5064, 5059, 5061, + 11766, 5068, 5066, 5065, 5057, 5073, 5080, 5084, 5069, 5077, + 5086, 5090, 5114, 5110, 5102, 5100, 5123, 5135, 5118, 5104, + + 5127, 5113, 5117, 5111, 5129, 5133, 5138, 5144, 5121, 5158, + 5162, 5163, 5150, 5149, 5155, 5146, 5179, 5156, 5174, 5183, + 5173, 5177, 5184, 5189, 5190, 5193, 5191, 5166, 5200, 5197, + 5218, 5204, 5207, 5210, 5228, 5229, 5233, 5236, 5230, 5231, + 5232, 5234,11766,11766, 5260,11766, 5250, 5249, 5253, 5261, + 5263, 5270, 5267, 5265, 5268, 5269, 5278, 5291, 5286, 5287, + 5308, 5299, 5303, 5311, 5296, 5302, 5310, 5297, 5313, 5321, + 11766, 5314,11766, 5327, 5312, 5331, 5324, 5350, 5329,11766, + 5353,11766, 5352, 5357, 5345, 5346, 5348,11766, 5363, 5344, + 5347, 5359, 5358, 5369, 5372, 5377, 5381, 5396, 5388, 5386, + + 5382, 5394, 5389, 5391, 5392, 5404, 5410, 5408, 5414, 5415, + 5421, 5412, 5439, 5425, 5449, 5431, 5427, 5429, 5451, 5438, + 5456,11766, 5460, 5469, 5459, 5458, 5463, 5465, 5473, 5479, + 5482, 5480, 5472, 5495, 5509, 5498, 5485, 5506, 5496, 5512, + 5500, 5513, 5508, 5521, 5514, 5543, 5542, 5554, 5530, 5556, + 5553,11766, 5538, 5555, 5540, 5541, 5557, 5565,11766, 5561, + 5568, 5551, 5563, 5593, 5582, 5579, 5584, 5598, 5602, 5586, + 5595, 5585, 5630, 5615, 5581, 5611, 5632,11766, 5610, 5612, + 5620, 5637, 5614, 5625, 5623, 5658, 5650, 5660, 5664, 5663, + 5666, 5643, 5662, 5654, 5659, 5681, 5674, 5699, 5700, 5691, + + 5702, 5682, 5698, 5704, 5707, 5692, 5693, 5701, 5697, 5695, + 5718, 5719, 5721, 5722, 5726, 5725, 5743, 5749, 5737, 5748, + 11766, 5742, 5745, 5746, 5763, 5741, 5764, 5765, 5752, 5784, + 5788, 5786,11766, 5767, 5776, 5792, 5790, 5798, 5791, 5794, + 5777, 5782, 5811, 5827, 5816, 5829, 5825, 5823,11766, 5833, + 11766, 5822, 5817, 5843, 5845, 5851, 5847, 5844, 5852, 5850, + 5876, 5868, 5864, 5879, 5870, 5880, 5890, 5867, 5891, 5882, + 5886, 5889, 5900, 5912, 5906, 5895, 5905, 5899, 5927, 5915, + 5923, 5920, 5926, 5925, 5949, 5932, 5931,11766,11766, 5944, + 5948, 5954, 5953, 5957, 5951, 5984, 5971, 5965, 5976, 5988, + + 5992, 5978, 5999, 5996, 6000, 6004, 6025,11766, 6016, 6013, + 6010, 6029, 6019, 6012, 6017, 6009, 6015, 6040, 6024, 6052, + 6044,11766, 6043, 6046, 6054, 6058, 6051, 6071, 6059,11766, + 6061,11766, 6056, 6057, 6070, 6079, 6077, 6083, 6081, 6090, + 6098, 6086, 6091, 6112, 6120, 6125, 6119, 6110, 6124, 6108, + 6113, 6115, 6129, 6117, 6141, 6121, 6137, 6127,11766, 6159, + 6142, 6161, 6158, 6146, 6169, 6170, 6167, 6154,11766, 6168, + 11766, 6172, 6178, 6181, 6179, 6185, 6207, 6194, 6203, 6197, + 6217, 6214, 6206, 6218, 6210, 6221, 6211, 6224, 6209,11766, + 6212, 6233, 6237, 6242, 6239, 6255, 6259, 6260, 6245, 6267, + + 11766, 6266, 6273, 6262, 6269, 6258, 6275, 6276, 6279, 6281, + 6292, 6287, 6289, 6294, 6297, 6304, 6308, 6290, 6316, 6305, + 6318, 6322, 6324, 6310, 6336, 6339, 6337, 6329, 6358, 6338, + 11766, 6345, 6343, 6350, 6351, 6354, 6378, 6368, 6375, 6383, + 6387, 6370, 6391, 6392, 6377, 6379, 6394, 6399, 6404, 6397, + 6409,11766, 6418, 6405, 6421, 6406, 6413, 6425, 6416, 6431, + 6428, 6417, 6433, 6446, 6432, 6442, 6448, 6449, 6450, 6457, + 6471, 6473, 6452, 6464, 6468, 6475, 6474, 6476, 6490, 6478, + 11766, 6511, 6493, 6489, 6506, 6514, 6503, 6527, 6517, 6509, + 6523, 6513, 6521, 6528, 6520, 6538, 6531, 6535, 6548, 6543, + + 6560, 6541,11766,11766, 6563, 6547, 6558, 6571,11766, 6568, + 6559, 6584, 6562, 6573, 6566, 6587, 6581, 6570, 6588, 6589, + 6593, 6579, 6611, 6613, 6595, 6608,11766, 6622, 6620, 6631, + 6607, 6626, 6636, 6635,11766, 6623, 6641, 6643, 6639, 6646, + 6630, 6647, 6656, 6658, 6653, 6673, 6659, 6652, 6680, 6683, + 6664, 6694, 6685, 6689, 6698, 6679, 6686, 6711,11766, 6700, + 6696, 6714, 6695, 6705, 6716, 6721,11766, 6725, 6726, 6732, + 6728, 6740, 6737, 6741, 6747, 6754, 6739, 6748, 6758, 6760, + 6768, 6762, 6763, 6764, 6759, 6775, 6786, 6789, 6785, 6780, + 6787, 6799,11766, 6795, 6807, 6797, 6800, 6808,11766, 6819, + + 6838, 6834,11766, 6841, 6813, 6832, 6830, 6846,11766, 6831, + 6844, 6835, 6850, 6827, 6854, 6833, 6858, 6857, 6862, 6856, + 6861, 6866, 6871, 6875,11766, 6878, 6873, 6891,11766, 6895, + 6894, 6900, 6904, 6905, 6908, 6914, 6910, 6909, 6915, 6920, + 6907, 6924, 6931,11766, 6911, 6949,11766, 6942, 6944, 6933, + 6934, 6935, 6958,11766, 6943, 6951, 6960, 6964, 6957, 6969, + 6975, 6976, 6968, 6977, 6985, 6971, 6981, 6988, 6995, 7004, + 6993, 6987, 7001, 7007, 7003,11766, 7028, 7015, 7014, 7026, + 6991, 7018, 7030, 7031, 7027, 7042, 7036,11766,11766, 7051, + 11766, 7056, 7045, 7052, 7055,11766, 7050, 7066, 7069, 7064, + + 7072, 7082, 7075, 7079, 7076, 7087, 7093,11766, 7090, 7096, + 11766, 7092, 7098, 7110, 7099, 7111, 7100, 7109, 7131, 7134, + 7112, 7136, 7138, 7126, 7139, 7120, 7145, 7137, 7174, 7107, + 7180,11766, 7164, 7144, 7173, 7176, 7169, 7168, 7189, 7193, + 7196, 7190, 7201,11766, 7200, 7202, 7212, 7213, 7215,11766, + 11766, 7224,11766, 7216, 7226,11766, 7225, 7236, 7227, 7229, + 7239, 7241, 7247,11766, 7248, 7255, 7258, 7252, 7265, 7274, + 11766, 7275, 7279, 7254, 7271, 7263, 7260, 7286, 7282, 7281, + 7317, 7292,11766, 7296, 7307, 7302, 7304, 7323, 7319, 7310, + 7306, 7333, 7327, 7334, 7340, 7343, 7329, 7344, 7345, 7350, + + 7349, 7352, 7354, 7361, 7356, 7363, 7351,11766, 7371, 7385, + 7378, 7379, 7404, 7374, 7399, 7391,11766, 7396, 7398, 7406, + 7412,11766, 7401, 7426, 7413, 7415, 7402, 7425, 7427, 7432, + 7430, 7436, 7441, 7453,11766, 7439, 7452, 7440, 7457, 7466, + 7465, 7463,11766,11766, 7480,11766, 7470, 7473, 7479, 7477, + 7484, 7493, 7488, 7501, 7505, 7498, 7500, 7508, 7513, 7504, + 7515, 7514,11766, 7528, 7389, 7511, 7553, 7392, 7529, 7546, + 11766, 7542, 7531,11766, 7532,11766, 7539, 7536, 7564, 7567, + 7556, 7570, 7571, 7563, 7569, 7578,11766, 7576, 7573, 7581, + 7580, 7586, 7605, 7610, 7611, 7591,11766, 7613, 7599, 7618, + + 7603,11766, 7600, 7624, 7612, 7621, 7637, 7642, 7639, 7638, + 7614, 7648, 7645, 7658, 7656, 7644, 7663, 7652, 7650, 7671, + 7661, 7672, 7687, 7680, 7678, 7701,11766, 7694, 7685, 7690, + 7703, 7683, 7684, 7705, 7713, 7714, 7716, 7718, 7729, 7720, + 11766, 7712,11766, 7731, 7728, 7719, 7746, 7730, 7759, 7755, + 7763, 7749, 7743, 7754, 7761, 7771, 7778, 7777, 7780, 7769, + 7770, 7787, 7809,11766, 7791, 7801, 7788, 7807, 7811, 7792, + 7816, 7812,11766, 7819, 7805, 7806, 7829, 7818,11766, 7821, + 7822, 7835, 7842, 7837, 7857, 7844, 7856, 7860, 7863, 7851, + 7858, 7846, 7869, 7862, 7872, 7877, 7876,11766, 7875, 7874, + + 7881, 7898, 7887, 7904, 7906, 7907, 7914, 7911, 7894, 7901, + 7917,11766, 7908, 7926, 7920, 7922,11766, 7928, 7936, 7929, + 7939, 7955, 7958, 7941, 7942, 7944, 7956, 7963, 7981, 7950, + 7994,11766, 7970, 7976, 7991, 7985, 7986, 7987, 7992, 7989, + 8016, 7997, 8008, 8027,11766, 8034, 8026, 8035, 8036, 8043, + 8024, 8033, 8029, 8055, 8053, 8052,11766, 8054, 8061, 8079, + 8056, 8060, 8074, 8068, 8075, 8097, 8091, 8094, 8082, 8087, + 8101, 8083, 8106, 8110, 8111, 8113, 8098, 8102, 8118, 8128, + 11766, 8116,11766, 8121, 8126, 8143, 8155, 8151, 8145, 8159, + 8148, 8153, 8162, 8170,11766, 8142, 8150, 8164, 8180, 8187, + + 8189, 8191, 8197,11766, 8188, 8185, 8193, 8194,11766, 8207, + 8204, 8212, 8221, 8226, 8176, 8213, 8241, 8222, 8243,11766, + 8245, 8247, 8246, 8178, 8216, 8249, 8252, 8240, 8255, 8248, + 8261, 8266, 8265, 8263, 8268, 8272, 8289,11766, 8292, 8295, + 8297, 8299, 8300, 8293, 8301, 8288, 8313, 8303, 8320,11766, + 8307, 8316, 8318, 8321, 8328, 8345, 8326, 8347, 8323, 8348, + 8350, 8353, 8355, 8339, 8340, 8343, 8366, 8367, 8364,11766, + 8375, 8374, 8391, 8397, 8400, 8395, 8402,11766, 8398,11766, + 8385, 8392, 8408, 8410, 8415,11766, 8417, 8423, 8418, 8425, + 8427,11766,11766, 8435, 8405, 8429, 8446, 8440, 8448,11766, + + 11766, 8457,11766, 8442,11766, 8444, 8443,11766,11766, 8456, + 8437, 8471, 8464, 8468,11766, 8469, 8476, 8477,11766, 8479, + 11766, 8497, 8473, 8501, 8478, 8485, 8505,11766, 8492, 8512, + 8506, 8513, 8514,11766, 8519, 8517, 8516, 8528, 8509, 8532, + 11766, 8530, 8539, 8541, 8553, 8549, 8543, 8545, 8559, 8552, + 8544, 8562, 8566,11766, 8568, 8565, 8589, 8579, 8590, 8585, + 8595, 8601, 8588, 8591, 8592, 8608, 8587, 8616, 8615, 8610, + 8618, 8623, 8638, 8639, 8629, 8642, 8628, 8643, 8650, 8652, + 8656, 8637, 8634, 8647, 8662, 8664, 8671, 8667, 8669, 8672, + 8690, 8681, 8693, 8683, 8694, 8691, 8677, 8700, 8686, 8696, + + 8702, 8698, 8711, 8709, 8717, 8713, 8715, 8727, 8722, 8733, + 8724, 8748, 8740, 8754, 8738, 8742, 8744,11766, 8743, 8756, + 8758, 8771, 8763, 8764, 8786, 8779, 8790, 8791, 8792, 8794, + 8785, 8798,11766,11766,11766, 8800, 8801,11766, 8803, 8814, + 8822, 8815, 8820,11766, 8817, 8821, 8816, 8825, 8826, 8831, + 8830, 8849, 8836, 8852, 8853, 8854,11766, 8864, 8869, 8860, + 8862, 8866, 8885,11766, 8877, 8888, 8872, 8876, 8882, 8898, + 8891, 8889, 8892, 8904, 8895, 8919, 8922, 8901, 8924, 8929, + 8916, 8912, 8932,11766, 8940, 8942, 8949, 8927, 8934, 8933, + 8939, 8941, 8957, 8964, 8950, 8951, 8953, 8963, 8972, 8961, + + 8982, 8984, 8992, 8991, 8994,11766, 8976, 8996,11766, 8997, + 8985, 8990, 9005, 9010, 9007, 9008, 9011, 9019, 9017,11766, + 11766, 9020, 9023, 9024, 9026, 9030, 9031, 9048, 9050, 9044, + 9052,11766, 9047, 9054, 9058, 9066, 9060, 9065,11766, 9067, + 9071, 9075, 9073, 9095, 9092, 9083, 9091, 9086, 9093, 9107, + 9094, 9103,11766, 9111, 9116, 9120, 9126, 9129, 9113, 9137, + 9139, 9136, 9130, 9143, 9138, 9148,11766, 9140,11766,11766, + 11766, 9159, 9153, 9147, 9149, 9164, 9165, 9166, 9172, 9174, + 9175, 9168, 9170, 9185,11766, 9194,11766,11766, 9193,11766, + 9202, 9189, 9204, 9205, 9195, 9206, 9210,11766, 9208,11766, + + 9219, 9221, 9228, 9238, 9239, 9242, 9229, 9249, 9233, 9257, + 9251, 9256, 9241, 9245, 9267, 9268, 9270, 9250,11766, 9279, + 9272, 9277, 9289, 9292,11766,11766, 9288, 9283, 9284, 9301, + 9300, 9313, 9307, 9316, 9291, 9322, 9320, 9326, 9328, 9327, + 9314, 9330, 9323, 9340, 9342, 9341, 9347, 9345,11766, 9354, + 9357, 9349,11766, 9358,11766, 9372, 9373, 9375, 9348, 9369, + 9374, 9381, 9386, 9385, 9388, 9396, 9393,11766,11766, 9400, + 9408, 9389,11766,11766, 9405, 9406, 9409, 9411, 9428, 9427, + 9412,11766, 9432, 9433, 9436, 9425, 9435, 9450, 9443, 9447, + 11766, 9457,11766, 9453,11766, 9471, 9449, 9454, 9451, 9455, + + 11766, 9464, 9467, 9491, 9487, 9480, 9470, 9484,11766, 9481, + 9492,11766, 9501, 9500, 9509, 9502, 9507, 9504, 9508,11766, + 9524, 9528, 9532, 9526,11766, 9529, 9527, 9530, 9516, 9540, + 9546, 9535, 9549, 9561,11766, 9563, 9566, 9569, 9568,11766, + 9575,11766, 9559, 9573, 9571, 9587, 9572,11766, 9588, 9589, + 9592, 9590,11766, 9580, 9594, 9603, 9610, 9607, 9611,11766, + 9622, 9605,11766, 9606, 9625, 9627, 9629, 9616, 9641, 9632, + 9630, 9646, 9647, 9644, 9657,11766,11766, 9667, 9662, 9651, + 9658, 73, 9669, 9643, 9656, 9659, 9671, 9685, 9686, 9687, + 9670, 9696, 9691,11766,11766, 9699, 9697, 9694,11766, 9703, + + 9704,11766, 9683, 9706, 9714, 9722, 9720, 9719, 9705, 9723, + 9730, 9745, 9734, 9751, 9741, 9746, 9750,11766, 9756, 9774, + 9757, 9753, 9759, 9778, 9787, 9789, 9792, 9775, 9794, 9777, + 9769, 9798, 9801, 9786, 9804, 9810, 9806, 9803, 9820, 9821, + 9822,11766, 9823, 9832, 9843, 9830, 9844, 9847, 9849, 9833, + 11766, 9852, 9848, 9858, 9856,11766, 9862, 9857, 9868, 9863, + 9878, 9882,11766, 9874, 9886, 9894, 9893, 9889, 9880, 9885, + 9888, 9890, 9911,11766, 9895, 9918, 9913, 9914, 9930, 9931, + 9937, 9933, 9938, 9924,11766, 9935,11766,11766,11766, 9941, + 9944, 9953,11766, 9947, 9958, 9951, 9957,11766, 9952, 9981, + + 9973, 9988, 9974,11766,11766,11766, 9962, 9985, 9983,11766, + 9971, 9993,11766, 9984,11766, 9995,11766, 9999,10000,10006, + 10012,11766,10019,10011,11766,10017,10022,10015,10036,11766, + 10030,10041,10045,10038,10033,10034,10031,10051,10061,11766, + 11766,10064,10069,10068,10071,10075,10065,10067,10063,10077, + 10081,10090,11766,10062,10086,11766,10097,10100,10102,10111, + 10096,10103,10104,11766,10113,11766,10116,11766,10108,10109, + 10124,10140,10132,10131,10134,10142,10149,10135,10145,10136, + 10151,10161,10148,10159,10165,10173,10168,11766,11766,10194, + 10176,11766,10192,10191,10196,11766,10178,11766,10201,11766, + + 10186,10188,11766,10203,10193,10205,11766,11766,10206,10207, + 10213,10212,10215,10216,10225,11766,10223,10231,10220,10232, + 10229,10243,10252,10259,10246,10240,10251,10262,11766,10268, + 11766,10254,10271,10272,11766,11766,10263,10266,10276,10283, + 10279,10280,10297,10291,10296,10288,10314,10298,10299,10293, + 10322,10323,10330,10318,10331,10336,10341,11766,11766,11766, + 10325,10326,10327,10343,10356,10359,10362,11766,10361,10349, + 11766,10366,10372,10373,10358,10384,10363,10382,11766,10375, + 10379,10376,10383,10391,10393,10399,10386,11766,10416,10417, + 10419,10420,10407,10422,10429,10430,10431,10423,10414,10433, + + 10424,10439,10441,10440,11766,11766,10453,10447,11766,10455, + 10461,11766,11766,10450,11766,10448,10449,10454,10456,10483, + 11766,10479,10459,10468,10475,11766,10474,10482,10493,10488, + 10497,10499,10500,10502,10501,10512,10503,10515,11766,10507, + 10537,10516,10514,10540,10542,11766,11766,10527,10538,11766, + 10551,10550,10539,10561,10546,10549,10559,10563,11766,10567, + 11766,10566,10574,10569,10571,10576,10580,10588,10584,10577, + 11766,10597,10590,10593,10601,11766,10604,10596,10608,10616, + 10628,11766,10629,10618,10635,10636,11766,10624,10639,10645, + 11766,11766,11766,10646,10647,10650,11766,11766,11766,10652, + + 10665,11766,10657,10671,10656,10659,11766,10663,11766,11766, + 10680, 7975,10689,10682,10697,10687,11766,10688,10690,10700, + 10683,10692,11766,10704,10708,11766,10694,10716,10717,10714, + 10713,10723,10724,10709,10712,10733,10734,10719,10727,11766, + 11766,10728,10735,10741,10739,10743,11766,10749,10761,10766, + 10773,10768,10778,10781,10782,10783,10762,10772,10786,10803, + 10797,10801,10792,10805,10795,10802,10818,10806,10821,10808, + 10830,10826,10827,10822,10833,11766,11766,10831,10832,10840, + 11766,10841,10842,11766,10843,11766,10855,10856,10862,10866, + 11766,10871,10872,10874,10875,10850,11766,10870,10880,11766, + + 11766,10864,10865,10877,10890,10894,11766,11766,10886,10887, + 10888,10898,11766,10901,10910,10907,10919,10914,10911,10908, + 10930,10921,10939,11766,10925,10942,11766,11766,11766,10944, + 10932,10951,10935,10962,10937,11766,10965,10970,10958,10969, + 10956,10966,10964,11766,10967,10977,11766,11766,10983,10988, + 11766,10978,11766,11766,10982,10992,11766,11766,11766,11766, + 11766,11766,11766,11766,10993,11013,11766,11009,11014,11015, + 11002,11007,11004,11766,11011,11028,11032,11033,11766,11037, + 11766,11029,11038,11042,11041,11043,11766,11048,11766,11068, + 11044,11055,11071,11070,11063,11056,11064,11073,11069,11085, + + 11081,11094,11093,11095,11105,11090,11103,11108,11097,11118, + 11119,11114,11131,11123,11128,11130,11143,11132,11142,11766, + 11766,11766,11766,11146,11136,11126,11153,11158,11164,11163, + 11166,11165,11172,11177,11178,11179,11176,11192,11159,11185, + 11206,11188,11195,11205,11213,11194,11216,11217,11218,11766, + 11220,11221,11223,11766,11230,11208,11236,11238,11224,11227, + 11242,11766,11234,11241,11766,11232,11244,11766,11766,11260, + 11263,11259,11251,11277,11279,11261,11268,11265,11280,11282, + 11766,11293,11766,11766,11766,11766,11283,11286,11766,11288, + 11766,11766,11278,11294,11766,11302,11296,11306,11313,11766, + + 11304,11327,11300,11321,11323,11318,11330,11333,11339,11766, + 11766,11326,11331,11349,11348,11351,11353,11766,11346,11356, + 11365,11376,11380,11379,11382,11383,11358,11391,11766,11373, + 11378,11385,11390,11396,11402,11395,11766,11415,11405,11414, + 11407,11408,11435,11412,11420,11436,11437,11438,11766,11442, + 11766,11439,11445,11440,11450,11454,11456,11461,11458,11463, + 11766,11766,11766,11465,11453,11766,11467,11486,11470,11490, + 11495,11494,11497,11479,11503,11507,11505,11506,11509,11512, + 11520,11521,11523,11522,11766,11766,11511,11524,11766,11537, + 11539,11526,11533,11555,11766,11557,11546,11558,11560,11559, + + 11567,11766,11562,11563,11568,11766,11571,11766,11766,11573, + 11572,11587,11580,11581,11766,11766,11766,11646,11653,11660, + 11667,11674,11681,11688, 100,11695,11702,11709,11716,11723, + 11730,11737,11744,11751,11758 } ; -static const flex_int16_t yy_def[4034] = +static const flex_int16_t yy_def[4136] = { 0, - 4015, 1, 4016, 4016, 4017, 4017, 4018, 4018, 4019, 4019, - 4020, 4020, 4021, 4021, 4022, 4022, 4015, 4023, 4015, 4015, - 4015, 4015, 4024, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4025, 4015, 4015, - 4015, 4025, 4026, 4015, 4015, 4015, 4026, 4027, 4015, 4015, - 4015, 4015, 4027, 4028, 4015, 4015, 4015, 4028, 4029, 4015, - 4030, 4015, 4029, 4029, 4031, 4015, 4015, 4015, 4015, 4031, - 4032, 4015, 4015, 4015, 4032, 4023, 4023, 4015, 4033, 4024, - 4033, 4024, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4025, 4025, 4026, 4026, 4027, 4027, - 4015, 4028, 4028, 4029, 4029, 4030, 4030, 4029, 4031, 4031, - 4015, 4032, 4032, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4029, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4029, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4015, 4023, 4023, 4015, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4029, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4029, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4015, - 4015, 4023, 4023, 4015, 4015, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4029, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4015, 4023, 4023, 4023, 4015, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4015, 4015, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4015, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, - 4023, 4023, 4023, 4029, 4029, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, - 4029, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4015, 4015, 4023, 4015, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4029, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4015, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4015, 4015, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4015, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4015, 4023, 4023, - 4023, 4029, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4015, - 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4029, 4023, 4015, - 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, - 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4015, 4015, 4023, 4015, 4023, 4023, 4023, 4023, 4015, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4015, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4015, 4015, 4023, 4015, 4023, 4023, 4015, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - - 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4015, 4015, 4023, 4015, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4029, 4023, - 4023, 4023, 4023, 4015, 4023, 4023, 4015, 4023, 4015, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, - 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4015, 4023, 4015, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4015, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4015, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4029, 4023, 4015, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4015, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4015, - 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, - 4023, 4015, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - 4015, 4023, 4015, 4023, 4015, 4023, 4023, 4015, 4015, 4023, - 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4015, 4023, - - 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4029, 4023, - 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4015, - 4015, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4015, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4015, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4015, 4015, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, - 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4015, - 4015, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4015, 4015, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4029, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - 4023, 4023, 4023, 4023, 4023, 4015, 4015, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, - 4023, 4023, 4015, 4023, 4015, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4015, 4023, - 4023, 4023, 4015, 4015, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4015, 4023, 4015, 4023, 4015, 4023, 4023, 4023, 4023, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, - 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4015, - - 4023, 4023, 4023, 4023, 4015, 4023, 4015, 4023, 4023, 4023, - 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4015, 4015, 4023, 4023, 4023, 4023, 4029, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4015, - 4023, 4023, 4015, 4023, 4023, 4015, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4015, - 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4015, 4023, 4015, 4015, 4015, 4023, 4023, - 4023, 4015, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, - 4023, 4023, 4015, 4015, 4015, 4023, 4023, 4023, 4015, 4023, - 4023, 4015, 4023, 4015, 4023, 4015, 4023, 4023, 4023, 4023, - 4015, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4015, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4015, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4015, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4015, 4023, 4015, 4023, 4015, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4015, 4015, 4023, 4023, 4015, - 4023, 4023, 4023, 4015, 4023, 4015, 4023, 4015, 4023, 4023, - 4015, 4023, 4023, 4023, 4015, 4015, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4015, 4023, 4015, 4023, 4023, 4023, 4015, 4015, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4015, 4015, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4015, 4023, 4023, - 4015, 4023, 4023, 4015, 4015, 4023, 4015, 4023, 4023, 4023, - 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, - 4023, 4023, 4015, 4015, 4023, 4023, 4015, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4015, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4015, 4023, - 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4015, 4015, 4015, - 4023, 4023, 4023, 4015, 4015, 4015, 4023, 4023, 4015, 4023, - 4023, 4023, 4023, 4015, 4023, 4015, 4015, 4023, 4023, 4023, - 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4015, - 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4015, 4015, 4023, 4023, 4023, 4023, 4023, 4015, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4015, 4023, - 4023, 4023, 4015, 4023, 4023, 4015, 4023, 4015, 4023, 4023, - 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4015, 4023, - 4023, 4015, 4015, 4015, 4023, 4023, 4023, 4023, 4015, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - 4023, 4023, 4015, 4015, 4015, 4023, 4023, 4023, 4023, 4023, - 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - 4023, 4023, 4015, 4015, 4023, 4023, 4015, 4023, 4015, 4015, - 4023, 4023, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, - - 4023, 4023, 4015, 4015, 4023, 4023, 4023, 4023, 4015, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4015, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4015, 4015, 4015, 4015, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4015, 4023, 4023, - 4015, 4023, 4023, 4015, 4015, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4015, 4015, - - 4015, 4015, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4015, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - 4015, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, - 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, 4023, - 4023, 4023, 4015, 4015, 4023, 4023, 4015, 4023, 4023, 4023, - 4023, 4023, 4015, 4023, 4023, 4023, 4023, 4023, 4023, 4015, - - 4023, 4023, 4023, 4015, 4023, 4015, 4015, 4023, 4023, 4023, - 4023, 4023, 4015, 4015, 0, 4015, 4015, 4015, 4015, 4015, - 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, - 4015, 4015, 4015 + 4117, 1, 4118, 4118, 4119, 4119, 4120, 4120, 4121, 4121, + 4122, 4122, 4123, 4123, 4124, 4124, 4117, 4125, 4117, 4117, + 4117, 4117, 4126, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4127, 4117, 4117, + 4117, 4127, 4128, 4117, 4117, 4117, 4128, 4129, 4117, 4117, + 4117, 4117, 4129, 4130, 4117, 4117, 4117, 4130, 4131, 4117, + 4132, 4117, 4131, 4131, 4133, 4117, 4117, 4117, 4117, 4133, + 4134, 4117, 4117, 4117, 4134, 4125, 4125, 4117, 4135, 4126, + 4135, 4126, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4127, 4127, 4128, 4128, 4129, 4129, + 4117, 4130, 4130, 4131, 4131, 4132, 4132, 4131, 4133, 4133, + 4117, 4134, 4134, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4131, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4131, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4131, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4131, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4117, 4125, 4117, 4117, 4125, 4125, 4117, 4117, 4125, + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4131, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4117, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4117, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4117, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, + 4131, 4131, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4131, + 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4117, 4117, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4117, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4117, + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4131, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + 4117, 4125, 4125, 4125, 4131, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4117, 4117, 4125, 4125, 4125, 4125, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + + 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4131, 4125, 4117, 4125, 4125, 4125, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4117, 4125, 4125, 4117, 4125, 4125, 4125, + 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4117, 4125, + 4117, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4117, + 4117, 4125, 4117, 4125, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4117, 4117, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4117, 4125, 4125, 4131, 4125, 4125, 4125, 4125, + 4117, 4125, 4125, 4117, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, + + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4117, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4117, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4117, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4131, 4125, 4117, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4117, + 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4117, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4117, + + 4117, 4125, 4117, 4125, 4117, 4125, 4125, 4117, 4117, 4125, + 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4117, 4125, + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4131, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4117, 4117, 4117, 4125, 4125, 4117, 4125, 4125, + 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, + 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4117, 4117, + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4117, 4125, 4117, 4117, 4125, 4117, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4117, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4131, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + 4125, 4125, 4125, 4125, 4117, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + 4125, 4125, 4117, 4125, 4117, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4117, 4125, + 4125, 4125, 4117, 4117, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4117, 4125, 4117, 4125, 4117, 4125, 4125, 4125, 4125, 4125, + + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, + 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4117, + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4117, + 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4117, 4117, 4125, 4125, 4125, + 4125, 4131, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4117, 4117, 4125, 4125, 4125, 4117, 4125, + + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4117, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4117, 4125, 4117, 4117, 4117, 4125, + 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + + 4125, 4125, 4125, 4117, 4117, 4117, 4125, 4125, 4125, 4117, + 4125, 4125, 4117, 4125, 4117, 4125, 4117, 4125, 4125, 4125, + 4125, 4117, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4117, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4117, 4125, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4117, 4125, 4117, 4125, 4117, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4117, 4125, + 4125, 4117, 4125, 4125, 4125, 4117, 4125, 4117, 4125, 4117, + + 4125, 4125, 4117, 4125, 4125, 4125, 4117, 4117, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + 4117, 4125, 4125, 4125, 4117, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4117, 4117, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4117, 4117, 4125, 4125, 4117, 4125, + 4125, 4117, 4117, 4125, 4117, 4125, 4125, 4125, 4125, 4125, + 4117, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4117, 4117, 4125, 4125, 4117, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4117, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4117, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, + 4117, 4117, 4117, 4125, 4125, 4125, 4117, 4117, 4117, 4125, + + 4125, 4117, 4125, 4125, 4125, 4125, 4117, 4125, 4117, 4117, + 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, + 4125, 4125, 4117, 4125, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, + 4117, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4117, 4117, 4125, 4125, 4125, + 4117, 4125, 4125, 4117, 4125, 4117, 4125, 4125, 4125, 4125, + 4117, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4117, + + 4117, 4125, 4125, 4125, 4125, 4125, 4117, 4117, 4125, 4125, + 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4117, 4125, 4125, 4117, 4117, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4117, 4125, 4125, 4117, 4117, 4125, 4125, + 4117, 4125, 4117, 4117, 4125, 4125, 4117, 4117, 4117, 4117, + 4117, 4117, 4117, 4117, 4125, 4125, 4117, 4125, 4125, 4125, + 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4117, 4125, + 4117, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, + 4117, 4117, 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, + 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4117, 4125, 4125, 4117, 4125, 4125, 4117, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4117, 4125, 4117, 4117, 4117, 4117, 4125, 4125, 4117, 4125, + 4117, 4117, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4117, + + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4117, 4125, + 4117, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4117, 4117, 4117, 4125, 4125, 4117, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, 4125, + 4125, 4125, 4125, 4125, 4117, 4117, 4125, 4125, 4117, 4125, + 4125, 4125, 4125, 4125, 4117, 4125, 4125, 4125, 4125, 4125, + + 4125, 4117, 4125, 4125, 4125, 4117, 4125, 4117, 4117, 4125, + 4125, 4125, 4125, 4125, 4117, 4117, 0, 4117, 4117, 4117, + 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, + 4117, 4117, 4117, 4117, 4117 } ; -static const flex_int16_t yy_nxt[11526] = +static const flex_int16_t yy_nxt[11833] = { 0, 18, 19, 20, 21, 22, 23, 22, 18, 18, 18, 18, 18, 22, 24, 25, 26, 27, 28, 29, 18, @@ -1761,13 +1794,13 @@ static const flex_int16_t yy_nxt[11526] = 60, 61, 62, 123, 22, 59, 60, 61, 62, 87, 22, 65, 66, 67, 65, 66, 67, 88, 165, 165, - 86, 89, 360, 52, 122, 87, 52, 172, 172, 57, + 86, 89, 361, 52, 122, 87, 52, 172, 172, 57, 123, 57, 175, 76, 77, 78, 79, 63, 22, 76, 77, 78, 79, 63, 22, 82, 83, 84, 68, 99, 87, 68, 19, 20, 21, 70, 71, 72, 19, 20, 21, 70, 71, 72, 82, 83, 84, 124, 110, 182, 182, 80, 73, 164, 175, 87, 99, 80, 73, 87, - 438, 91, 85, 91, 91, 87, 91, 1460, 111, 88, + 440, 91, 85, 91, 91, 87, 91, 1469, 111, 88, 74, 87, 91, 89, 124, 110, 74, 165, 165, 73, 164, 85, 172, 172, 167, 73, 114, 167, 112, 87, 163, 183, 133, 178, 115, 111, 100, 87, 87, 92, @@ -1796,1231 +1829,1265 @@ static const flex_int16_t yy_nxt[11526] = 91, 274, 203, 181, 144, 145, 179, 146, 179, 179, 87, 179, 192, 87, 213, 202, 87, 142, 217, 180, - 292, 143, 1293, 87, 87, 86, 309, 86, 86, 203, + 292, 143, 1301, 87, 87, 86, 309, 86, 86, 203, 86, 144, 145, 177, 146, 147, 86, 91, 148, 91, 91, 213, 91, 195, 196, 149, 197, 292, 91, 150, 151, 204, 198, 87, 199, 214, 87, 87, 87, 200, 201, 175, 147, 173, 87, 148, 226, 87, 87, 205, 195, 196, 149, 197, 87, 92, 150, 151, 218, 198, 207, 199, 214, 87, 210, 211, 200, 201, 216, 208, - 223, 87, 212, 226, 171, 87, 205, 235, 505, 225, + 223, 87, 212, 226, 171, 87, 205, 235, 507, 225, - 87, 219, 87, 170, 220, 218, 348, 207, 168, 229, + 87, 219, 87, 170, 220, 218, 349, 207, 168, 229, 227, 210, 211, 230, 224, 216, 208, 221, 222, 212, 87, 87, 87, 239, 235, 87, 225, 87, 219, 231, 228, 220, 87, 87, 232, 234, 229, 227, 87, 233, 230, 224, 87, 87, 221, 222, 237, 240, 87, 241, 239, 242, 243, 238, 245, 244, 231, 228, 87, 246, 87, 232, 234, 87, 87, 87, 233, 252, 87, 251, - 166, 87, 4015, 237, 240, 87, 241, 87, 242, 243, + 166, 87, 4117, 237, 240, 87, 241, 87, 242, 243, 238, 245, 244, 247, 250, 87, 246, 248, 257, 254, - 253, 87, 352, 249, 252, 87, 251, 87, 255, 259, + 253, 87, 353, 249, 252, 87, 251, 87, 255, 259, - 87, 258, 87, 266, 256, 87, 354, 87, 260, 358, + 87, 258, 87, 266, 256, 87, 355, 87, 260, 359, 247, 250, 87, 263, 248, 257, 254, 253, 87, 261, 249, 264, 267, 262, 87, 255, 259, 87, 258, 265, - 266, 256, 87, 272, 270, 260, 275, 4015, 87, 268, + 266, 256, 87, 272, 270, 260, 275, 4117, 87, 268, 263, 87, 269, 273, 87, 271, 261, 87, 87, 267, 262, 87, 279, 87, 87, 276, 265, 284, 281, 280, - 272, 270, 282, 275, 277, 283, 268, 87, 4015, 269, - 273, 87, 271, 87, 4015, 87, 278, 285, 4015, 279, - 87, 87, 276, 4015, 284, 281, 280, 87, 286, 282, - 87, 277, 283, 169, 4015, 169, 169, 174, 169, 174, + 272, 270, 282, 275, 277, 283, 268, 87, 4117, 269, + 273, 87, 271, 87, 4117, 87, 278, 285, 4117, 279, + 87, 87, 276, 4117, 284, 281, 280, 87, 286, 282, + 87, 277, 283, 169, 4117, 169, 169, 174, 169, 174, 174, 287, 174, 278, 285, 91, 288, 91, 91, 290, 91, 179, 175, 179, 179, 286, 179, 291, 87, 295, - 289, 296, 297, 87, 300, 298, 293, 4015, 287, 87, + 289, 296, 297, 87, 300, 298, 293, 4117, 287, 87, 87, 87, 299, 294, 301, 87, 290, 87, 87, 302, - 87, 4015, 306, 177, 291, 87, 295, 289, 296, 297, - 87, 300, 298, 293, 87, 318, 303, 87, 319, 299, - 294, 301, 304, 305, 87, 87, 302, 4015, 307, 306, - 308, 310, 320, 87, 323, 311, 322, 321, 324, 326, - 327, 87, 318, 325, 87, 319, 87, 1043, 87, 304, - 305, 329, 312, 822, 87, 307, 87, 308, 87, 87, - - 87, 323, 311, 322, 87, 324, 326, 330, 328, 4015, - 325, 331, 87, 332, 87, 333, 87, 361, 329, 312, - 313, 87, 87, 336, 337, 314, 87, 87, 4015, 87, - 315, 338, 87, 344, 330, 328, 316, 317, 331, 345, - 332, 334, 333, 87, 335, 4015, 87, 313, 87, 87, - 336, 337, 314, 87, 346, 87, 87, 315, 338, 347, - 344, 87, 4015, 316, 317, 350, 345, 349, 334, 355, - 87, 335, 339, 353, 363, 340, 351, 341, 357, 4015, - 87, 346, 366, 356, 87, 359, 347, 4015, 362, 342, - 4015, 343, 4015, 87, 349, 367, 368, 87, 87, 339, - - 353, 87, 340, 351, 341, 357, 87, 87, 364, 87, - 356, 87, 359, 365, 87, 362, 342, 87, 343, 369, - 370, 373, 367, 368, 87, 371, 87, 376, 375, 4015, - 374, 377, 378, 87, 372, 364, 381, 4015, 388, 87, - 365, 87, 87, 87, 379, 384, 369, 370, 373, 87, - 87, 87, 371, 87, 376, 375, 87, 374, 377, 378, - 382, 372, 380, 381, 386, 383, 385, 87, 391, 387, - 87, 379, 384, 87, 87, 87, 389, 390, 392, 393, - 394, 397, 396, 4015, 87, 87, 87, 87, 395, 380, - 87, 386, 87, 385, 398, 391, 387, 399, 401, 406, - - 405, 87, 87, 389, 390, 402, 393, 394, 397, 396, - 87, 400, 403, 87, 404, 395, 408, 409, 4015, 87, - 87, 4015, 407, 413, 411, 87, 87, 87, 87, 87, - 87, 87, 402, 421, 410, 418, 412, 414, 400, 403, - 87, 404, 87, 87, 409, 87, 415, 416, 87, 407, - 413, 411, 175, 417, 87, 419, 420, 87, 422, 87, - 87, 410, 418, 412, 414, 87, 87, 423, 425, 424, - 428, 4015, 426, 415, 416, 427, 433, 429, 87, 87, - 417, 4015, 419, 420, 87, 430, 431, 434, 87, 87, - 87, 87, 435, 450, 423, 87, 424, 428, 87, 426, - - 87, 432, 427, 87, 429, 87, 436, 439, 87, 437, - 442, 87, 430, 431, 434, 440, 87, 87, 441, 435, - 446, 87, 445, 452, 443, 87, 451, 454, 432, 453, - 447, 4015, 87, 436, 439, 87, 437, 442, 444, 87, - 448, 87, 440, 87, 87, 441, 87, 446, 87, 445, - 87, 443, 449, 451, 87, 87, 453, 447, 87, 87, - 87, 455, 459, 457, 458, 444, 462, 448, 460, 464, - 4015, 463, 4015, 87, 4015, 87, 466, 467, 456, 449, - 87, 465, 4015, 4015, 87, 472, 87, 469, 455, 87, - 457, 458, 461, 462, 87, 87, 464, 468, 463, 470, - - 87, 87, 87, 466, 467, 456, 87, 87, 465, 471, - 87, 87, 472, 473, 469, 474, 476, 478, 87, 461, - 477, 4015, 87, 480, 468, 488, 470, 479, 489, 503, - 499, 490, 475, 4015, 504, 87, 471, 87, 87, 87, - 473, 4015, 474, 87, 87, 498, 523, 477, 87, 87, - 480, 87, 488, 87, 479, 489, 4015, 499, 490, 475, - 481, 87, 500, 501, 502, 482, 507, 4015, 483, 87, - 506, 4015, 498, 484, 485, 486, 487, 87, 87, 4015, - 4015, 4015, 4015, 87, 510, 516, 511, 481, 87, 500, - 501, 502, 482, 87, 87, 483, 87, 506, 87, 517, - - 484, 485, 486, 487, 491, 514, 492, 508, 493, 515, - 509, 510, 87, 511, 512, 513, 4015, 87, 494, 495, - 496, 87, 497, 87, 87, 518, 517, 87, 87, 519, - 4015, 491, 514, 492, 508, 493, 515, 509, 520, 522, - 87, 512, 513, 524, 528, 494, 495, 496, 521, 497, - 526, 87, 518, 4015, 525, 87, 519, 87, 87, 527, - 87, 87, 87, 4015, 4015, 520, 522, 529, 534, 530, - 524, 87, 533, 4015, 535, 521, 87, 526, 531, 87, - 536, 525, 537, 4015, 4015, 532, 527, 539, 538, 540, - 87, 542, 550, 87, 529, 534, 530, 541, 549, 533, - - 547, 4015, 87, 4015, 87, 531, 87, 536, 548, 537, - 87, 87, 532, 543, 539, 538, 540, 551, 87, 87, - 567, 564, 4015, 87, 541, 565, 544, 547, 87, 545, - 87, 546, 87, 568, 87, 548, 588, 87, 569, 87, - 543, 572, 175, 566, 551, 87, 582, 567, 564, 87, - 570, 87, 565, 544, 87, 585, 545, 581, 546, 552, - 568, 553, 4015, 588, 87, 569, 571, 554, 572, 87, - 566, 555, 589, 582, 87, 596, 556, 570, 583, 557, - 87, 593, 87, 584, 581, 87, 552, 87, 553, 590, - 586, 663, 592, 571, 554, 4015, 591, 587, 555, 589, - - 87, 87, 596, 556, 595, 87, 557, 558, 600, 559, - 87, 87, 594, 87, 87, 597, 590, 586, 87, 592, - 604, 87, 560, 591, 587, 561, 601, 562, 87, 563, - 87, 595, 87, 87, 558, 600, 559, 602, 603, 594, - 608, 598, 597, 4015, 87, 87, 4015, 604, 607, 560, - 599, 611, 561, 601, 562, 4015, 563, 573, 574, 605, - 87, 606, 4015, 609, 602, 603, 87, 575, 576, 577, - 578, 579, 87, 87, 580, 607, 614, 599, 611, 613, - 610, 87, 87, 87, 573, 574, 605, 87, 606, 87, - 609, 612, 87, 617, 575, 576, 577, 578, 579, 616, - - 87, 580, 615, 4015, 87, 626, 613, 610, 87, 620, - 87, 618, 619, 4015, 621, 87, 87, 622, 612, 623, - 617, 87, 624, 625, 4015, 638, 616, 87, 87, 615, - 87, 4015, 626, 627, 628, 87, 620, 633, 87, 630, - 87, 621, 631, 635, 622, 634, 623, 649, 87, 624, - 625, 629, 638, 87, 651, 87, 636, 632, 87, 637, - 627, 628, 87, 87, 633, 87, 630, 87, 87, 631, - 635, 650, 634, 639, 640, 653, 87, 654, 629, 87, - 652, 651, 4015, 636, 632, 641, 637, 642, 4015, 87, - 655, 4015, 87, 87, 658, 656, 87, 4015, 650, 661, - - 639, 640, 653, 87, 4015, 662, 657, 652, 659, 87, - 4015, 668, 641, 660, 642, 643, 87, 655, 87, 87, - 87, 658, 656, 644, 645, 87, 661, 646, 647, 87, - 87, 648, 662, 657, 665, 659, 664, 87, 666, 670, - 660, 667, 643, 87, 87, 671, 4015, 669, 673, 674, - 644, 645, 87, 672, 646, 647, 87, 87, 648, 87, - 693, 665, 87, 664, 677, 666, 670, 87, 667, 87, - 87, 87, 671, 675, 669, 673, 674, 678, 679, 87, - 672, 676, 680, 681, 87, 4015, 682, 87, 683, 684, - 685, 677, 87, 688, 87, 686, 4015, 87, 4015, 87, - - 675, 87, 689, 4015, 678, 679, 687, 87, 676, 680, - 681, 87, 87, 682, 691, 683, 684, 685, 87, 87, - 688, 87, 686, 692, 87, 690, 4015, 694, 87, 689, - 695, 87, 696, 687, 702, 701, 87, 697, 698, 699, - 87, 691, 87, 87, 707, 87, 700, 709, 706, 87, - 692, 87, 690, 87, 694, 87, 87, 695, 703, 696, - 704, 702, 701, 705, 697, 698, 699, 87, 87, 708, - 713, 712, 87, 700, 795, 706, 87, 710, 714, 87, - 711, 715, 87, 87, 722, 703, 718, 704, 87, 87, - 705, 720, 716, 719, 87, 717, 708, 721, 712, 724, - - 87, 795, 87, 87, 710, 714, 87, 711, 715, 728, - 87, 87, 725, 718, 723, 87, 87, 4015, 720, 716, - 719, 87, 717, 87, 721, 727, 724, 729, 730, 732, - 731, 87, 87, 734, 87, 726, 728, 733, 87, 87, - 736, 723, 737, 735, 87, 87, 749, 738, 4015, 750, - 87, 87, 727, 87, 729, 730, 732, 731, 87, 87, - 734, 87, 726, 4015, 733, 87, 4015, 736, 4015, 737, - 735, 747, 87, 749, 738, 739, 750, 748, 87, 751, - 740, 752, 741, 87, 753, 4015, 4015, 87, 742, 754, - 743, 4015, 755, 744, 745, 87, 756, 4015, 747, 4015, - - 746, 87, 739, 87, 748, 4015, 751, 740, 752, 741, - 757, 753, 87, 758, 87, 742, 754, 743, 765, 755, - 744, 745, 87, 756, 762, 760, 767, 746, 761, 763, - 87, 769, 766, 759, 4015, 87, 87, 757, 87, 764, - 758, 770, 87, 87, 768, 765, 772, 771, 87, 87, - 87, 762, 760, 767, 776, 761, 777, 773, 769, 766, - 759, 87, 774, 775, 87, 778, 764, 87, 770, 87, - 87, 768, 87, 772, 771, 87, 779, 87, 780, 781, - 87, 776, 782, 777, 773, 784, 783, 87, 4015, 774, - 775, 786, 778, 785, 87, 788, 87, 792, 87, 787, - - 87, 789, 793, 779, 4015, 780, 781, 87, 802, 782, - 87, 87, 784, 783, 87, 791, 87, 790, 786, 794, - 785, 4015, 175, 87, 792, 796, 787, 87, 789, 87, - 798, 87, 799, 797, 87, 87, 801, 800, 803, 804, - 87, 805, 791, 806, 790, 807, 794, 87, 87, 808, - 820, 811, 796, 87, 809, 87, 87, 798, 87, 799, - 797, 810, 87, 87, 800, 803, 87, 812, 816, 87, - 806, 87, 807, 87, 87, 813, 808, 87, 811, 87, - 821, 809, 814, 87, 817, 815, 819, 823, 810, 818, - 824, 87, 826, 87, 812, 816, 825, 4015, 827, 829, - - 87, 832, 813, 828, 830, 831, 4015, 87, 87, 814, - 87, 833, 815, 819, 834, 835, 87, 87, 841, 87, - 87, 836, 87, 87, 87, 87, 829, 837, 832, 839, - 87, 830, 831, 87, 87, 838, 840, 87, 833, 87, - 842, 834, 835, 843, 844, 87, 845, 87, 836, 87, - 87, 846, 849, 87, 837, 847, 839, 848, 87, 87, - 4015, 850, 838, 840, 87, 852, 87, 842, 87, 87, - 843, 844, 851, 845, 854, 855, 87, 856, 846, 849, - 87, 87, 847, 87, 848, 861, 853, 863, 850, 862, - 87, 4015, 852, 87, 87, 865, 87, 87, 866, 851, - - 857, 870, 855, 4015, 856, 858, 87, 864, 859, 860, - 867, 871, 861, 853, 863, 87, 862, 87, 87, 868, - 87, 869, 865, 87, 87, 866, 872, 857, 4015, 87, - 876, 87, 858, 87, 864, 859, 860, 867, 871, 873, - 877, 875, 880, 878, 879, 87, 868, 4015, 869, 87, - 87, 87, 87, 872, 881, 87, 883, 876, 882, 885, - 889, 874, 87, 4015, 87, 87, 873, 877, 875, 880, - 878, 879, 87, 884, 87, 886, 887, 888, 87, 891, - 87, 881, 87, 883, 87, 882, 87, 889, 874, 87, - 890, 893, 87, 87, 892, 894, 87, 895, 896, 897, - - 884, 900, 886, 887, 888, 87, 891, 898, 899, 87, - 87, 901, 87, 908, 904, 902, 910, 890, 893, 87, - 911, 892, 894, 87, 903, 896, 897, 87, 900, 87, - 905, 906, 907, 87, 909, 87, 87, 87, 901, 926, - 87, 904, 902, 87, 87, 87, 913, 911, 87, 914, - 912, 903, 87, 87, 918, 917, 87, 905, 906, 907, - 87, 909, 915, 929, 920, 919, 87, 916, 87, 87, - 4015, 87, 927, 913, 931, 928, 914, 912, 87, 930, - 87, 918, 917, 87, 936, 87, 87, 932, 933, 4015, - 929, 920, 919, 87, 87, 921, 4015, 922, 937, 927, - - 87, 931, 928, 934, 923, 4015, 930, 87, 87, 942, - 938, 924, 925, 87, 932, 933, 87, 1013, 935, 87, - 939, 940, 921, 944, 922, 937, 941, 87, 947, 946, - 934, 923, 87, 945, 87, 87, 942, 938, 924, 925, - 943, 87, 87, 948, 87, 935, 954, 939, 87, 949, - 944, 951, 87, 87, 87, 947, 946, 950, 87, 87, - 945, 952, 953, 955, 959, 956, 87, 943, 87, 87, - 948, 957, 87, 954, 963, 962, 949, 87, 951, 4015, - 958, 87, 4015, 87, 950, 1003, 960, 87, 952, 87, - 955, 959, 956, 964, 87, 961, 965, 966, 957, 968, - - 87, 4015, 962, 967, 970, 87, 87, 958, 969, 87, - 87, 87, 87, 960, 972, 4015, 87, 87, 4015, 971, - 964, 978, 961, 965, 966, 87, 968, 87, 87, 973, - 967, 970, 976, 974, 975, 969, 977, 979, 87, 980, - 87, 972, 87, 87, 87, 981, 971, 983, 978, 982, - 87, 984, 4015, 986, 4015, 87, 973, 985, 987, 976, - 974, 975, 87, 977, 979, 87, 980, 87, 87, 87, - 87, 988, 981, 989, 983, 87, 982, 990, 984, 87, - 986, 991, 992, 993, 985, 987, 87, 87, 998, 994, - 995, 4015, 996, 997, 999, 4015, 1000, 87, 988, 1021, - - 989, 87, 87, 87, 990, 1004, 87, 87, 991, 992, - 993, 87, 87, 87, 87, 998, 994, 995, 1001, 996, - 997, 999, 1002, 1000, 1005, 4015, 1007, 175, 1008, 1006, - 1009, 87, 1004, 4015, 1010, 1020, 87, 87, 1012, 87, - 4015, 1011, 87, 87, 87, 1001, 87, 1024, 87, 1002, - 1018, 1005, 87, 1007, 87, 1008, 1006, 1009, 87, 1014, - 1019, 1010, 1020, 1022, 1016, 1012, 1023, 1015, 1011, 1017, - 87, 87, 87, 87, 1024, 1027, 1025, 1018, 87, 1026, - 1028, 87, 1029, 1032, 87, 87, 1014, 1019, 1030, 1031, - 1022, 87, 87, 1023, 1015, 1033, 87, 87, 1034, 4015, - - 1046, 1042, 1027, 1025, 4015, 87, 1026, 87, 1044, 87, - 1032, 4015, 87, 87, 87, 1030, 1031, 4015, 87, 4015, - 1045, 87, 1033, 1049, 4015, 1034, 1035, 1046, 1042, 1036, - 4015, 1048, 1047, 1037, 1050, 1044, 1038, 87, 87, 1051, - 4015, 87, 1052, 1039, 1040, 87, 1041, 1045, 1053, 1054, - 1049, 87, 87, 1035, 1056, 1055, 1036, 1058, 1048, 1047, - 1037, 1050, 87, 1038, 87, 87, 1051, 87, 87, 1052, - 1039, 1040, 1057, 1041, 87, 1053, 1054, 1067, 1070, 87, - 1068, 1056, 1055, 4015, 87, 1069, 1071, 87, 1075, 87, - 4015, 87, 1072, 4015, 4015, 87, 4015, 4015, 1073, 1057, - - 1059, 1060, 87, 1061, 1067, 1070, 1062, 1068, 1076, 87, - 87, 1063, 1069, 1071, 1074, 1075, 87, 1064, 1065, 1072, - 1066, 87, 1078, 1083, 1077, 1073, 87, 1059, 1060, 1079, - 1061, 87, 1081, 1062, 87, 1076, 1080, 1082, 1063, 1084, - 1085, 1074, 1087, 87, 1064, 1065, 87, 1066, 1086, 1078, - 1083, 1077, 87, 1089, 1088, 1091, 1079, 1090, 1092, 1093, - 87, 4015, 4015, 1080, 87, 87, 1084, 1085, 87, 1087, - 87, 1095, 4015, 1099, 87, 1086, 87, 87, 1100, 87, - 1089, 1088, 87, 87, 1090, 1092, 1093, 1094, 1096, 1097, - 1101, 1098, 87, 1103, 87, 87, 87, 87, 1095, 87, - - 1099, 1102, 87, 1104, 87, 1100, 87, 1106, 87, 1108, - 1105, 1109, 1110, 1113, 1094, 1096, 1097, 1101, 1098, 87, - 1103, 1107, 87, 1114, 1115, 1119, 87, 1111, 1102, 87, - 1104, 1123, 1112, 87, 1106, 87, 1116, 1105, 1109, 87, - 1113, 87, 1117, 1120, 1121, 87, 1118, 1122, 1107, 87, - 87, 1115, 87, 87, 1125, 87, 1124, 87, 1123, 87, - 1126, 1128, 1130, 1116, 4015, 87, 1132, 1131, 1127, 1117, - 1120, 87, 1136, 1118, 1122, 87, 87, 87, 1140, 1139, - 87, 87, 1129, 1124, 87, 1134, 87, 87, 1128, 1130, - 87, 87, 1133, 1132, 1131, 1127, 87, 1135, 1137, 87, - - 1142, 87, 1138, 4015, 1141, 87, 87, 1184, 87, 1129, - 87, 1144, 1134, 87, 1143, 1146, 87, 1145, 87, 1133, - 87, 87, 1147, 1148, 1135, 1137, 87, 1142, 1149, 1138, - 1150, 1141, 87, 87, 87, 1151, 1152, 1153, 1144, 87, - 87, 1143, 1146, 1154, 1145, 1155, 4015, 87, 1156, 1147, - 1148, 1157, 87, 87, 1160, 1149, 87, 1150, 1161, 87, - 87, 1163, 1151, 1152, 1153, 87, 87, 87, 1158, 87, - 1154, 1162, 1155, 1159, 1164, 1156, 1165, 1166, 1157, 87, - 1169, 1160, 1167, 87, 87, 1161, 87, 1170, 1163, 1171, - 1168, 1172, 87, 1173, 4015, 87, 4015, 1174, 1162, 87, - - 87, 1164, 4015, 1165, 1166, 87, 87, 1169, 1175, 1167, - 1181, 1179, 4015, 87, 87, 87, 1171, 1168, 1172, 87, - 1173, 1176, 1177, 1178, 1174, 1182, 1185, 87, 87, 87, - 87, 1183, 1180, 87, 87, 1175, 87, 1181, 1179, 87, - 1186, 1190, 1191, 1187, 87, 1194, 4015, 1189, 1176, 1177, - 1178, 1193, 1182, 1185, 87, 87, 1188, 1195, 1183, 1180, - 87, 87, 87, 1192, 87, 87, 1199, 1186, 1190, 1191, - 1187, 1197, 87, 87, 1189, 1196, 87, 1205, 1193, 1198, - 1200, 1203, 87, 1188, 1195, 87, 87, 87, 87, 87, - 1192, 1201, 1202, 1199, 1204, 1206, 87, 1207, 1197, 1208, - - 87, 87, 1196, 1209, 1211, 1210, 1198, 1200, 1203, 87, - 87, 1212, 87, 1220, 1213, 1214, 87, 1217, 1201, 1202, - 1215, 1204, 1219, 87, 1207, 1221, 1222, 87, 1216, 1223, - 1209, 87, 1210, 1225, 1218, 87, 87, 87, 87, 87, - 87, 1213, 1214, 87, 1217, 87, 1224, 1215, 87, 1219, - 87, 1226, 1227, 1222, 1228, 1216, 1223, 87, 87, 4015, - 87, 1218, 1229, 87, 1230, 87, 1234, 1237, 1236, 1231, - 1239, 1235, 4015, 1224, 1238, 87, 87, 4015, 1226, 87, - 87, 1228, 1232, 1242, 1233, 1240, 87, 1241, 4015, 1229, - 87, 1230, 87, 87, 1237, 1236, 1231, 1239, 175, 87, - - 87, 1238, 1246, 1244, 1245, 87, 87, 1243, 1248, 1232, - 1242, 1233, 1240, 1247, 1241, 87, 1249, 87, 1250, 4015, - 1257, 1290, 87, 87, 87, 4015, 87, 4015, 1259, 1246, - 1244, 1245, 4015, 1261, 1243, 1248, 1258, 4015, 1260, 1262, - 1247, 87, 87, 1249, 4015, 1250, 1251, 1257, 1252, 1265, - 87, 87, 1253, 87, 1254, 1259, 87, 1263, 1264, 1255, - 87, 1267, 87, 1258, 1256, 1260, 1262, 1268, 4015, 1269, - 87, 1266, 1270, 1251, 87, 1252, 1265, 1271, 4015, 1253, - 87, 1254, 87, 87, 1263, 1264, 1255, 1272, 1267, 87, - 1273, 1256, 1283, 1280, 1268, 1274, 1269, 1276, 1266, 1281, - - 1282, 4015, 1277, 87, 87, 87, 1278, 1275, 87, 87, - 1285, 4015, 1286, 87, 1272, 1288, 1279, 1273, 87, 87, - 1280, 87, 1274, 87, 1276, 1284, 1281, 1282, 87, 1277, - 87, 87, 1287, 1278, 1275, 1289, 87, 1285, 1291, 1286, - 1292, 1294, 1288, 1279, 1295, 1296, 4015, 1297, 4015, 87, - 1305, 1307, 1284, 87, 87, 4015, 87, 87, 4015, 1287, - 1309, 4015, 1289, 1306, 87, 87, 4015, 87, 1308, 1310, - 87, 1295, 1296, 87, 1297, 1298, 1312, 1305, 1307, 1311, - 1299, 1313, 1300, 87, 1314, 87, 87, 1309, 1301, 87, - 1306, 87, 87, 1302, 1303, 1308, 1310, 87, 87, 1317, - - 1304, 87, 1298, 1312, 1315, 1316, 1311, 1299, 1313, 1300, - 87, 1314, 87, 87, 1318, 1301, 1319, 1322, 1320, 4015, - 1302, 1303, 1328, 1325, 1326, 1321, 1317, 1304, 87, 1327, - 1323, 1315, 1316, 87, 87, 1329, 87, 4015, 87, 87, - 1324, 1331, 1333, 1319, 1322, 1320, 87, 87, 1334, 87, - 87, 1326, 1321, 1330, 87, 1332, 1327, 1323, 1335, 87, - 1336, 87, 1329, 87, 1339, 1337, 87, 1324, 1331, 87, - 87, 1340, 1341, 1338, 87, 1334, 1346, 87, 87, 1343, - 1330, 1342, 1332, 87, 87, 1335, 1344, 1336, 1347, 87, - 87, 1345, 1337, 87, 1348, 87, 87, 1353, 1340, 1341, - - 1338, 87, 87, 1346, 87, 1349, 1343, 1350, 1342, 87, - 1351, 1355, 1352, 1344, 1357, 1347, 1354, 1360, 1345, 1356, - 1359, 1348, 87, 87, 87, 87, 87, 87, 1358, 87, - 87, 87, 1349, 1371, 1350, 1362, 1361, 1351, 1355, 1352, - 87, 1357, 87, 1354, 87, 1363, 1356, 1359, 87, 87, - 1369, 1365, 1364, 1366, 87, 1358, 1372, 1370, 1373, 1367, - 1368, 1377, 1362, 1361, 87, 87, 1378, 4015, 87, 1415, - 4015, 1438, 1363, 87, 4015, 87, 87, 1369, 1365, 1364, - 1366, 87, 87, 87, 1370, 1373, 1367, 1368, 87, 1374, - 1375, 1376, 1383, 87, 1379, 1381, 87, 1380, 87, 1382, - - 1391, 87, 87, 1384, 87, 87, 1385, 87, 1386, 87, - 87, 1387, 1388, 4015, 1390, 87, 1374, 1375, 1376, 1383, - 87, 1379, 1381, 87, 1380, 87, 1382, 1391, 87, 1389, - 1384, 1392, 1393, 1385, 87, 1386, 1394, 1400, 1387, 1388, - 87, 1390, 1395, 1396, 87, 87, 4015, 1399, 4015, 87, - 1397, 1398, 1401, 1406, 4015, 1402, 1389, 1409, 1392, 1393, - 87, 87, 87, 87, 1400, 1403, 1404, 1407, 87, 1395, - 1405, 87, 87, 87, 1399, 87, 87, 1397, 1398, 1401, - 1406, 87, 1402, 1408, 1409, 1410, 1412, 87, 87, 87, - 1411, 1416, 1403, 1404, 1407, 1414, 1413, 1405, 1418, 1417, - - 1425, 87, 87, 1419, 1423, 87, 87, 87, 87, 87, - 1408, 1420, 1410, 1412, 1422, 1426, 1421, 1411, 1416, 1424, - 87, 87, 87, 1413, 87, 1418, 1417, 87, 87, 87, - 1419, 1423, 87, 87, 1427, 1428, 1429, 1430, 1420, 1432, - 4015, 1422, 1436, 1421, 4015, 1431, 1424, 87, 1433, 1435, - 1434, 1437, 4015, 4015, 4015, 4015, 87, 87, 87, 87, - 4015, 1439, 1428, 1429, 1440, 1441, 87, 87, 1446, 87, - 87, 87, 1431, 87, 87, 1433, 1435, 1434, 1437, 87, - 1442, 1444, 87, 1451, 87, 1443, 1445, 87, 1439, 87, - 1448, 1440, 1441, 87, 1447, 1446, 1449, 1452, 1450, 87, - - 1454, 1455, 4015, 4015, 4015, 87, 87, 1442, 1444, 4015, - 87, 87, 1443, 1445, 1453, 87, 87, 1448, 1457, 1458, - 1462, 1447, 87, 1449, 1456, 1450, 87, 1454, 87, 87, - 1459, 87, 87, 1461, 87, 1463, 1465, 1466, 87, 87, - 1467, 1453, 87, 87, 87, 1457, 1458, 1462, 1464, 1468, - 87, 1456, 1469, 1472, 1471, 87, 1470, 1459, 1473, 1476, - 1461, 175, 1463, 1465, 1466, 1475, 87, 87, 87, 1474, - 87, 1478, 1480, 1481, 87, 1464, 1468, 87, 87, 1469, - 1472, 1471, 1477, 1470, 87, 1473, 1476, 87, 1479, 1482, - 1483, 1485, 1475, 1488, 87, 87, 1474, 1486, 87, 1484, - - 4015, 1487, 87, 1492, 87, 87, 87, 1490, 87, 1477, - 87, 87, 1489, 87, 1493, 1479, 1482, 1483, 1485, 1491, - 1488, 1495, 87, 87, 1486, 87, 1484, 1494, 1487, 87, - 1492, 87, 1496, 87, 1490, 1497, 1498, 1499, 87, 1489, - 87, 1493, 1501, 1500, 1502, 1503, 1491, 87, 1495, 87, - 1504, 87, 4015, 1511, 1494, 1509, 87, 87, 1510, 1496, - 87, 87, 87, 1498, 1499, 1505, 87, 1512, 1513, 1501, - 1500, 1502, 1503, 1515, 1506, 87, 1507, 1504, 87, 1508, - 1511, 1516, 1509, 1514, 87, 1510, 87, 87, 87, 1519, - 1517, 1520, 1505, 1518, 87, 1513, 1521, 87, 87, 1522, - - 1515, 1506, 87, 1507, 87, 87, 1508, 87, 1516, 1523, - 1514, 1524, 1525, 87, 87, 1526, 1519, 1517, 1520, 1527, - 1518, 1528, 1529, 1521, 1533, 87, 1522, 87, 1530, 1531, - 1532, 87, 1537, 87, 4015, 1534, 87, 1544, 1524, 1525, - 87, 87, 1526, 87, 87, 1541, 1527, 87, 87, 1529, - 87, 1533, 87, 87, 1535, 1530, 1531, 1532, 1536, 1537, - 1538, 1540, 1534, 1542, 1544, 87, 87, 1543, 1545, 1539, - 87, 1546, 1541, 87, 1547, 87, 1550, 87, 87, 4015, - 4015, 1535, 4015, 4015, 87, 1536, 87, 1538, 1540, 1548, - 1542, 1553, 87, 1560, 1543, 1545, 1539, 1551, 1546, 1552, - - 1549, 1547, 1554, 1555, 87, 87, 87, 1556, 87, 87, - 1561, 87, 1557, 1558, 87, 87, 1548, 87, 1553, 1559, - 87, 1562, 87, 1563, 1551, 87, 1552, 1549, 1564, 1554, - 1555, 87, 1565, 1567, 1556, 87, 1566, 1561, 1574, 1557, - 1558, 87, 1568, 87, 87, 1573, 1559, 1569, 1572, 1570, - 1563, 87, 87, 87, 1571, 1564, 87, 1575, 87, 1565, - 1567, 1583, 87, 1566, 87, 1574, 1586, 1589, 1584, 1568, - 1591, 4015, 1573, 1585, 1569, 1572, 4015, 4015, 1587, 1588, - 4015, 87, 87, 87, 1575, 1576, 87, 4015, 1583, 1577, - 87, 87, 1578, 1579, 1589, 1584, 1590, 1580, 87, 1592, - - 1585, 87, 87, 1581, 87, 1587, 1588, 1582, 1598, 1593, - 1599, 87, 1576, 1594, 87, 1603, 1577, 1596, 1604, 1578, - 1579, 87, 1595, 1590, 1580, 1597, 1592, 1605, 87, 1611, - 1581, 87, 87, 1601, 1582, 1598, 1593, 1599, 1600, 87, - 1594, 1602, 87, 87, 1596, 87, 1606, 87, 1607, 1595, - 87, 87, 1597, 1609, 1605, 87, 87, 1608, 1610, 1613, - 1601, 87, 1612, 1615, 87, 1600, 87, 87, 1602, 1623, - 1614, 1622, 4015, 1606, 1616, 1607, 4015, 1624, 1633, 87, - 1609, 1634, 87, 87, 1608, 1610, 87, 1628, 87, 1612, - 1615, 87, 87, 87, 1625, 1626, 1623, 1614, 1622, 1627, - - 1629, 1616, 1617, 87, 1624, 87, 4015, 1618, 87, 1619, - 87, 1620, 87, 1621, 1628, 87, 1631, 1630, 1637, 1632, - 87, 1639, 1638, 87, 87, 87, 1627, 1629, 1635, 1617, - 1642, 4015, 87, 1636, 1618, 87, 1619, 87, 1620, 87, - 1621, 1640, 1641, 1631, 1630, 1637, 1632, 87, 1639, 1638, - 1643, 1650, 87, 1644, 1645, 1648, 1646, 1642, 1649, 87, - 87, 1647, 87, 87, 87, 4015, 87, 1651, 1640, 1641, - 1653, 87, 1655, 1656, 87, 4015, 1652, 1643, 1650, 1659, - 1644, 1645, 1654, 1646, 87, 1649, 87, 87, 1647, 87, - 87, 1660, 87, 87, 1651, 87, 1657, 1653, 1661, 1655, - - 1656, 87, 1658, 1652, 87, 87, 1659, 1662, 1663, 1654, - 87, 1664, 4015, 1665, 1667, 1668, 1669, 1666, 87, 1670, - 1671, 1677, 87, 1657, 1672, 1661, 87, 1673, 1682, 1658, - 87, 4015, 4015, 87, 87, 1663, 87, 87, 1664, 87, - 1665, 1667, 1668, 87, 1666, 1680, 1670, 87, 87, 87, - 87, 1672, 1674, 1675, 1673, 1676, 1678, 1679, 87, 87, - 87, 87, 1688, 87, 1681, 1683, 1686, 87, 1684, 87, - 1687, 87, 1680, 1685, 87, 87, 1689, 1690, 4015, 1674, - 1675, 1695, 1676, 1678, 1679, 1692, 87, 87, 1691, 1688, - 87, 1681, 1683, 1686, 87, 1684, 1694, 1687, 87, 87, - - 1685, 87, 1693, 1689, 1690, 87, 1696, 87, 1695, 1697, - 1698, 1699, 1692, 1700, 4015, 1691, 1702, 1703, 87, 1701, - 87, 87, 1704, 1694, 1707, 1705, 1706, 4015, 87, 1693, - 87, 1711, 87, 1696, 87, 87, 1697, 1698, 1699, 87, - 1700, 1708, 1709, 1702, 1710, 1714, 1701, 87, 87, 87, - 87, 1720, 1705, 1706, 87, 1712, 87, 1713, 87, 87, - 87, 1715, 87, 1716, 87, 1717, 1718, 87, 1708, 1709, - 87, 1710, 1714, 87, 1719, 1721, 1722, 175, 87, 1723, - 87, 1724, 1712, 87, 1713, 1725, 4015, 1730, 1715, 1729, - 1716, 1726, 1717, 1718, 4015, 87, 1727, 87, 87, 1732, - - 4015, 1719, 1728, 1722, 1733, 4015, 1723, 87, 1731, 87, - 1735, 87, 1725, 87, 87, 87, 1729, 87, 1726, 87, - 1736, 1734, 1737, 1727, 87, 1738, 1732, 87, 1739, 1728, - 87, 1733, 1740, 1741, 87, 1731, 87, 1735, 1742, 1743, - 1745, 87, 87, 1744, 1746, 1749, 1750, 1736, 1734, 1737, - 87, 87, 1738, 87, 87, 1739, 1751, 1747, 87, 1740, - 87, 87, 1748, 1752, 87, 1742, 1743, 1745, 1753, 1758, - 1744, 1746, 1749, 1750, 1754, 87, 87, 1755, 1756, 1760, - 87, 1757, 1759, 1751, 1761, 4015, 87, 87, 1762, 87, - 1752, 1763, 87, 1765, 1764, 1753, 1758, 1770, 1766, 87, - - 87, 1754, 4015, 1767, 1755, 1756, 1760, 87, 1757, 1759, - 87, 87, 1768, 87, 87, 1762, 87, 1769, 1763, 87, - 1771, 1764, 1773, 1772, 1770, 87, 87, 1774, 1776, 1775, - 1767, 87, 1778, 1777, 87, 87, 1780, 1784, 1781, 1768, - 4015, 87, 87, 1779, 1769, 87, 87, 1771, 1782, 1773, - 1772, 87, 87, 1785, 1774, 1776, 1775, 87, 1783, 1778, - 1777, 87, 87, 1780, 1787, 1781, 87, 1786, 87, 87, - 1779, 1788, 87, 1791, 1789, 1782, 1790, 1792, 87, 1796, - 1785, 87, 1793, 1794, 87, 1783, 87, 1795, 87, 1797, - 1799, 1787, 87, 1800, 1786, 1804, 87, 1805, 1788, 87, - - 1791, 1789, 87, 1790, 1792, 87, 1796, 1798, 87, 1793, - 1794, 87, 1801, 87, 1795, 1802, 1797, 1799, 1803, 87, - 1800, 87, 1804, 1806, 87, 87, 1808, 1807, 4015, 87, - 1809, 1812, 1811, 87, 1798, 1810, 1814, 87, 1813, 1801, - 87, 1815, 1802, 87, 1816, 1803, 4015, 4015, 1817, 4015, - 4015, 1818, 87, 1808, 1807, 87, 87, 87, 1812, 1811, - 87, 1821, 1810, 1822, 1823, 1813, 1825, 1828, 87, 1832, - 1819, 1824, 1820, 87, 87, 1817, 87, 87, 1818, 1826, - 87, 87, 87, 1827, 4015, 1829, 87, 87, 87, 1830, - 1822, 1823, 87, 1825, 1828, 87, 87, 1819, 1824, 1820, - - 1831, 87, 1833, 1836, 1834, 1835, 1826, 1840, 1837, 1838, - 1827, 87, 1829, 87, 1839, 1841, 1830, 87, 1842, 87, - 1843, 1845, 87, 1851, 87, 1844, 4015, 1831, 87, 1833, - 87, 1834, 1835, 87, 1840, 87, 1846, 1853, 1847, 87, - 1852, 87, 1841, 1848, 87, 1842, 87, 1843, 1845, 1849, - 1850, 87, 1844, 1855, 1858, 87, 87, 1854, 87, 87, - 87, 1856, 87, 1846, 1860, 1847, 87, 1852, 1861, 87, - 1848, 1857, 87, 87, 1859, 1862, 1849, 1850, 1863, 1864, - 1855, 1865, 87, 87, 1854, 87, 87, 87, 1856, 87, - 1871, 1860, 1870, 4015, 1872, 1866, 87, 1868, 1857, 1867, - - 87, 1859, 1862, 87, 87, 1863, 1864, 87, 1865, 1869, - 87, 1876, 1873, 1875, 1877, 87, 87, 1871, 87, 1870, - 87, 1872, 1866, 1874, 1868, 1878, 1867, 1882, 87, 1880, - 1879, 87, 1881, 1889, 1883, 4015, 1869, 1887, 87, 1873, - 1875, 87, 87, 87, 87, 87, 1890, 87, 87, 1897, - 1874, 1884, 1878, 87, 1882, 1885, 1880, 1879, 1888, 1881, - 1889, 1883, 1891, 87, 1887, 1892, 1895, 1893, 1886, 1896, - 87, 1900, 1894, 1890, 87, 1898, 87, 87, 1884, 1901, - 87, 87, 1885, 87, 87, 1888, 1899, 87, 1902, 1891, - 1906, 87, 1892, 87, 1893, 1886, 1896, 1903, 1904, 1894, - - 87, 87, 1898, 87, 1908, 87, 1901, 1905, 87, 4015, - 1909, 87, 1907, 1899, 1910, 1902, 87, 1906, 1911, 87, - 87, 1912, 1913, 87, 1903, 1904, 1914, 87, 1915, 1917, - 1918, 1916, 1919, 4015, 1905, 1920, 87, 87, 87, 1907, - 1921, 1910, 4015, 4015, 87, 1923, 87, 1926, 1912, 1913, - 87, 87, 87, 1914, 87, 1922, 87, 1918, 1916, 87, - 87, 1925, 1920, 1928, 1924, 87, 87, 1921, 87, 87, - 87, 1927, 1923, 1929, 1926, 1930, 1931, 1932, 87, 1933, - 1934, 87, 1922, 1935, 87, 87, 1937, 1936, 1925, 87, - 1928, 1924, 87, 1941, 1940, 87, 1938, 4015, 1927, 87, - - 1929, 87, 1930, 1931, 1932, 87, 1933, 1943, 87, 87, - 1935, 1942, 87, 1937, 1936, 1939, 87, 87, 1944, 87, - 1941, 1940, 1946, 1938, 87, 1945, 1948, 1947, 4015, 1949, - 1950, 1951, 1952, 87, 1943, 87, 1954, 87, 1942, 87, - 87, 1953, 1939, 1955, 87, 1944, 1956, 1959, 87, 87, - 87, 4015, 1945, 1948, 1947, 87, 1949, 1950, 1951, 1952, - 1961, 1957, 1960, 1954, 87, 87, 1958, 1962, 1953, 4015, - 1955, 87, 1963, 87, 1959, 1964, 87, 1967, 175, 1970, - 1969, 87, 87, 1965, 1966, 1972, 1971, 1961, 87, 1960, - 87, 87, 87, 87, 1962, 1968, 1973, 87, 87, 1963, - - 1975, 1977, 1964, 1978, 1967, 87, 1970, 1969, 87, 1974, - 1965, 1966, 1972, 1971, 1981, 1979, 87, 1976, 87, 1980, - 1983, 87, 1968, 1973, 87, 87, 87, 1975, 87, 1982, - 1978, 1984, 1985, 1986, 1987, 1988, 1974, 87, 87, 87, - 1989, 1981, 1979, 1991, 1976, 1990, 1980, 87, 87, 4015, - 1992, 87, 87, 87, 1993, 87, 1982, 1995, 1984, 1996, - 1986, 1987, 87, 1994, 87, 87, 87, 1989, 1999, 1997, - 1991, 87, 1990, 2000, 4015, 2001, 87, 1992, 1998, 2002, - 87, 1993, 87, 87, 1995, 87, 1996, 87, 87, 2003, - 1994, 2004, 2009, 2008, 4015, 1999, 1997, 87, 87, 2010, - - 2000, 87, 2001, 2011, 87, 1998, 2002, 2005, 87, 2016, - 2006, 2013, 2015, 2014, 87, 2017, 2003, 2022, 2004, 2012, - 2008, 87, 2007, 2019, 87, 2018, 2010, 87, 87, 87, - 2011, 87, 2020, 87, 2005, 87, 2016, 2006, 2013, 2015, - 2014, 2021, 87, 87, 2022, 2023, 2012, 2024, 2025, 2007, - 2027, 2026, 2018, 2028, 2031, 87, 2032, 2030, 2033, 87, - 2029, 87, 2035, 87, 87, 87, 2038, 87, 2021, 2034, - 87, 87, 2023, 2037, 2040, 2025, 2039, 2027, 2026, 87, - 2028, 87, 4015, 87, 2030, 2036, 87, 2029, 87, 87, - 87, 87, 2041, 87, 87, 87, 2034, 2042, 87, 87, - - 2037, 2040, 2043, 2039, 2046, 2044, 2049, 2045, 2047, 87, - 2048, 87, 2036, 87, 87, 87, 2050, 87, 87, 2041, - 2053, 87, 2051, 87, 2042, 2052, 2054, 2055, 87, 2043, - 2057, 2046, 2044, 2049, 2045, 2047, 2056, 2048, 2058, 4015, - 2067, 2059, 87, 2050, 87, 87, 87, 2053, 87, 2051, - 87, 87, 2052, 2054, 2055, 2060, 2062, 2057, 2061, 2066, - 2063, 4015, 2065, 2056, 2068, 87, 87, 87, 2059, 87, - 87, 87, 2069, 4015, 2071, 2070, 2074, 87, 2064, 87, - 2072, 4015, 2060, 2062, 87, 2061, 2066, 2063, 87, 2065, - 87, 2068, 87, 2073, 87, 2075, 2076, 2077, 2079, 2069, - - 87, 2071, 2070, 2074, 87, 2064, 87, 2072, 2078, 2080, - 87, 4015, 2081, 2088, 87, 2082, 2083, 2089, 2090, 2086, - 2073, 87, 2075, 2076, 2077, 2079, 2084, 87, 87, 87, - 87, 2085, 2087, 2091, 87, 2078, 2080, 87, 87, 2081, - 2088, 2092, 2082, 2083, 87, 87, 2086, 2093, 87, 2094, - 87, 2095, 2096, 2084, 2097, 2098, 2101, 2099, 2085, 2087, - 2091, 87, 87, 2100, 2102, 2103, 87, 87, 2092, 2110, - 87, 87, 87, 2112, 2093, 2106, 2094, 87, 87, 2096, - 87, 2097, 2098, 2101, 2099, 87, 2104, 87, 2105, 2107, - 2100, 2102, 2103, 87, 87, 2113, 2110, 87, 2116, 87, - - 2108, 2111, 2106, 2109, 2114, 87, 2120, 2115, 2117, 2119, - 2118, 2121, 87, 2104, 87, 2105, 2107, 87, 87, 87, - 87, 2122, 87, 87, 87, 2116, 2123, 2108, 2111, 2126, - 2109, 2114, 2152, 2127, 2115, 2117, 2119, 2118, 87, 2128, - 2124, 87, 87, 87, 2129, 2125, 4015, 2130, 2122, 2132, - 87, 2131, 4015, 2123, 87, 87, 2126, 87, 2137, 87, - 2127, 2134, 87, 2133, 2135, 2138, 2128, 2124, 2136, 4015, - 2139, 2129, 2125, 87, 2130, 87, 2132, 2140, 2131, 87, - 2150, 87, 87, 2141, 2142, 2137, 87, 87, 2134, 87, - 2133, 2135, 2138, 87, 2143, 2136, 87, 2139, 2147, 2144, - - 2145, 2148, 2146, 87, 2140, 2149, 2151, 2153, 2154, 2155, - 2141, 2142, 87, 87, 87, 87, 2156, 2157, 87, 4015, - 2161, 4015, 87, 87, 2158, 2147, 87, 2145, 2148, 2146, - 87, 87, 2149, 2151, 2159, 2154, 2155, 2160, 87, 87, - 2162, 87, 2172, 2165, 2157, 4015, 2166, 2163, 87, 2167, - 87, 2158, 87, 2164, 87, 2168, 2173, 87, 2169, 2170, - 87, 2159, 2171, 87, 2160, 87, 87, 2162, 2176, 2172, - 87, 87, 2174, 2166, 2163, 87, 2167, 2175, 87, 2177, - 2164, 87, 2168, 2173, 87, 2169, 2170, 2178, 2180, 2171, - 87, 87, 87, 2181, 2182, 2176, 2183, 2184, 4015, 2174, - - 2185, 2187, 2186, 2188, 2175, 2189, 2177, 87, 2179, 87, - 87, 87, 2190, 2194, 87, 2197, 4015, 4015, 87, 87, - 87, 2182, 2192, 2183, 87, 87, 2191, 2185, 2187, 2186, - 87, 87, 2189, 87, 2193, 2179, 2196, 87, 2195, 2198, - 87, 4015, 2197, 87, 87, 87, 87, 2199, 2200, 2192, - 2201, 2202, 2207, 2191, 2206, 87, 2203, 2205, 4015, 87, - 2210, 2193, 2214, 2196, 4015, 2195, 2198, 2204, 87, 87, - 87, 2208, 87, 87, 2199, 2200, 87, 2201, 2202, 2207, - 87, 2206, 2211, 2203, 2205, 2209, 175, 87, 2212, 87, - 87, 2213, 2215, 2216, 2204, 2218, 2217, 87, 2208, 87, - - 2222, 2219, 2220, 87, 2224, 2223, 87, 87, 2221, 2211, - 87, 87, 2209, 87, 87, 2212, 87, 87, 2213, 2215, - 2216, 87, 2218, 2217, 87, 2225, 2226, 2222, 2219, 2220, - 4015, 2224, 2223, 2227, 2228, 2221, 2229, 2231, 2230, 2232, - 4015, 87, 87, 2234, 87, 2233, 2235, 2237, 4015, 2238, - 2236, 4015, 4015, 2226, 2239, 87, 2241, 87, 87, 2240, - 2227, 2228, 87, 87, 2231, 2230, 87, 87, 87, 87, - 4015, 2242, 2233, 2235, 2246, 87, 87, 2236, 87, 87, - 87, 2239, 2243, 2241, 87, 2244, 2240, 87, 2245, 2247, - 2248, 2249, 2250, 4015, 87, 4015, 87, 87, 2242, 2251, - - 2252, 2246, 2259, 2255, 87, 2260, 87, 2253, 87, 2243, - 87, 87, 2244, 2258, 87, 2245, 2247, 2248, 2249, 2250, - 2254, 87, 87, 2261, 2256, 87, 2251, 2252, 4015, 2259, - 2255, 2257, 87, 2262, 2253, 87, 2264, 2263, 2267, 87, - 2258, 2265, 2266, 2272, 87, 87, 87, 2254, 87, 87, - 2268, 2256, 2271, 87, 2269, 87, 2270, 2273, 2257, 2274, - 2262, 2275, 2280, 2264, 2263, 2267, 87, 87, 2265, 2266, - 87, 2276, 2281, 2282, 2277, 87, 2278, 2268, 87, 2271, - 87, 2269, 87, 2270, 87, 2279, 2274, 2283, 87, 87, - 2284, 87, 2286, 2285, 2289, 87, 2287, 87, 2276, 2281, - - 87, 2277, 87, 2278, 2290, 87, 87, 2288, 2291, 2292, - 2293, 87, 2279, 4015, 2283, 2295, 87, 87, 2294, 2298, - 2285, 2289, 87, 2287, 87, 87, 2296, 2297, 2299, 4015, - 2300, 2290, 87, 87, 2288, 2291, 87, 2293, 87, 2301, - 87, 87, 87, 2302, 2307, 2294, 2298, 2310, 4015, 4015, - 87, 87, 4015, 2296, 2297, 2299, 87, 2300, 2303, 2304, - 2305, 87, 2309, 2308, 2313, 2306, 2301, 2311, 2317, 87, - 2312, 2307, 87, 87, 87, 87, 2314, 87, 2315, 87, - 2319, 87, 2322, 2316, 87, 2303, 2304, 2305, 2318, 2309, - 2308, 2313, 2306, 2320, 2311, 2317, 2321, 2312, 87, 2323, - - 87, 2328, 4015, 2314, 2324, 87, 2325, 2319, 87, 87, - 87, 87, 2327, 2326, 87, 2318, 2330, 87, 87, 87, - 2320, 87, 2331, 2321, 2329, 87, 2323, 2332, 87, 87, - 2333, 2324, 87, 2325, 2334, 2335, 2337, 2336, 2340, 2327, - 2326, 2339, 87, 2330, 87, 2338, 2342, 87, 2341, 2331, - 2343, 2329, 87, 4015, 2332, 4015, 87, 2333, 2348, 87, - 2346, 87, 87, 87, 2336, 87, 87, 2347, 2339, 2345, - 2344, 87, 2338, 2342, 2350, 2341, 87, 87, 2349, 2351, - 87, 2355, 87, 2354, 87, 87, 87, 2346, 2358, 2352, - 2353, 87, 2356, 87, 2347, 2362, 2345, 2344, 2360, 87, - - 2357, 2350, 2359, 2363, 2366, 2349, 2351, 87, 87, 87, - 2354, 87, 2364, 2367, 2361, 87, 2352, 2353, 2365, 2356, - 87, 87, 2362, 2374, 87, 2368, 87, 2357, 2369, 2359, - 87, 2370, 4015, 2373, 2381, 87, 87, 87, 87, 2364, - 87, 2361, 2371, 87, 2375, 2365, 87, 87, 2372, 87, - 2374, 2378, 2368, 2376, 2380, 2369, 87, 87, 2370, 2379, - 2373, 87, 87, 2377, 87, 2384, 87, 2383, 87, 2371, - 2382, 2375, 87, 2386, 2389, 2372, 2385, 87, 2378, 87, - 2376, 2380, 87, 2390, 2388, 87, 2379, 2391, 87, 2387, - 2377, 87, 2384, 2397, 2393, 2392, 87, 2382, 87, 87, - - 2386, 2389, 87, 2385, 2395, 87, 2394, 2396, 2398, 2399, - 2390, 2388, 87, 2400, 87, 2402, 2387, 2405, 87, 87, - 2397, 2393, 2392, 2401, 4015, 2409, 4015, 87, 4015, 87, - 87, 2395, 2403, 2394, 2396, 2398, 2399, 2404, 87, 2406, - 87, 87, 2402, 2407, 87, 87, 2408, 87, 87, 2413, - 2401, 2410, 2409, 2411, 87, 2412, 87, 2415, 87, 2403, - 87, 2416, 87, 2414, 2404, 2417, 2406, 2418, 2420, 87, - 2407, 2419, 87, 2408, 4015, 2421, 2426, 2427, 2410, 87, - 2411, 87, 2412, 87, 2415, 2430, 2425, 2431, 2416, 2433, - 2414, 87, 2417, 87, 87, 2420, 2422, 87, 2419, 2424, - - 2428, 2423, 2421, 87, 87, 2429, 87, 2434, 87, 2432, - 87, 87, 87, 2425, 2435, 2436, 2433, 87, 2437, 87, - 2438, 2441, 87, 2422, 2439, 2440, 2424, 87, 2423, 2443, - 87, 2444, 87, 2442, 2434, 87, 2432, 2445, 87, 2446, - 2447, 87, 2436, 87, 2454, 2437, 87, 2438, 87, 2448, - 87, 2439, 2440, 87, 2450, 2449, 87, 2451, 2444, 87, - 2442, 87, 2452, 2453, 2445, 2460, 87, 2447, 2455, 87, - 87, 87, 87, 2456, 2457, 2459, 2448, 175, 2458, 2461, - 2462, 2450, 2449, 2463, 2451, 87, 2465, 87, 4015, 2452, - 2453, 87, 87, 2464, 2467, 2455, 2466, 87, 4015, 87, - - 2456, 87, 87, 2468, 87, 2458, 2461, 2462, 87, 2471, - 2478, 2469, 87, 2465, 87, 87, 2470, 87, 2472, 2474, - 2464, 2467, 2473, 2466, 2475, 87, 2479, 2476, 87, 2477, - 2468, 2483, 87, 87, 87, 4015, 2471, 2478, 2481, 2480, - 2482, 87, 87, 87, 87, 2472, 2474, 2484, 2489, 2473, - 87, 2475, 2485, 87, 2476, 87, 2477, 87, 2483, 87, - 87, 2487, 87, 2486, 2488, 2481, 2480, 2482, 2492, 2490, - 87, 2491, 87, 4015, 87, 2493, 2494, 2495, 2499, 2485, - 87, 87, 2496, 2500, 87, 2503, 87, 87, 2487, 2501, - 2486, 2488, 87, 87, 87, 87, 2490, 2497, 2491, 2502, - - 87, 87, 2493, 2494, 2495, 2499, 87, 87, 2498, 2496, - 2500, 87, 2503, 2504, 2505, 2506, 2501, 2507, 2508, 2509, - 4015, 87, 4015, 87, 2497, 2510, 2502, 2511, 2516, 87, - 2518, 87, 87, 4015, 4015, 2498, 2512, 2513, 87, 87, - 2504, 2505, 2506, 2514, 2507, 2508, 87, 87, 87, 87, - 2519, 2517, 2510, 2515, 2511, 87, 87, 2518, 2520, 2522, - 87, 87, 2521, 2512, 2513, 2523, 87, 2525, 87, 2524, - 2514, 87, 2526, 2529, 2528, 87, 2532, 2519, 2517, 4015, - 2515, 87, 2531, 87, 2530, 2520, 2522, 2527, 87, 2521, - 2534, 87, 87, 2533, 87, 87, 2524, 87, 87, 2526, - - 87, 2528, 87, 2532, 2535, 87, 2538, 2537, 2539, 2531, - 2540, 2530, 2536, 87, 2527, 4015, 87, 2534, 2542, 87, - 2533, 87, 87, 87, 2543, 2541, 2544, 2545, 4015, 2552, - 87, 2535, 2546, 2538, 2537, 2539, 87, 2540, 87, 2536, - 87, 2555, 87, 2547, 4015, 2542, 2553, 87, 2554, 2561, - 87, 2543, 2541, 2544, 2548, 2549, 2552, 2556, 2550, 87, - 2557, 2559, 2558, 87, 2560, 2562, 87, 87, 87, 4015, - 2547, 2551, 87, 2553, 2563, 2554, 87, 2564, 2566, 87, - 4015, 2548, 2549, 87, 2556, 2550, 87, 2557, 2559, 2558, - 87, 2560, 2562, 2567, 2565, 2571, 87, 2568, 2551, 2569, - - 87, 2563, 87, 87, 2564, 2566, 2572, 2570, 87, 2573, - 87, 2574, 2575, 87, 2576, 87, 2578, 87, 2580, 87, - 2567, 2565, 2571, 87, 2568, 87, 2569, 2579, 2577, 2581, - 87, 87, 4015, 2572, 2570, 87, 2573, 2582, 2574, 2575, - 87, 87, 2583, 2578, 2584, 87, 87, 2589, 2585, 2586, - 2588, 2587, 4015, 4015, 2579, 2577, 2581, 87, 87, 87, - 87, 2590, 4015, 2599, 2582, 2592, 87, 87, 2591, 2583, - 87, 2584, 2595, 2604, 2597, 2585, 2586, 2588, 2587, 87, - 87, 2593, 87, 87, 2600, 2596, 2594, 87, 2590, 2598, - 87, 87, 2592, 87, 2602, 2591, 2603, 2605, 2601, 2595, - - 2607, 2597, 2606, 87, 87, 87, 87, 2608, 2609, 2610, - 87, 2600, 2596, 87, 87, 2613, 2598, 87, 2611, 87, - 2615, 2602, 2616, 2603, 2605, 2601, 2612, 87, 2614, 2606, - 2618, 2619, 87, 2617, 2673, 2609, 2620, 87, 4015, 87, - 87, 87, 87, 87, 2623, 2611, 87, 2615, 87, 2616, - 2624, 87, 87, 2612, 2628, 2614, 87, 2618, 2619, 87, - 2617, 2621, 2625, 2620, 2622, 2627, 87, 2626, 2629, 87, - 2630, 2623, 87, 4015, 2631, 2637, 2632, 2624, 2633, 87, - 87, 2628, 2634, 87, 87, 2638, 4015, 2635, 2621, 87, - 4015, 2622, 2627, 87, 87, 2629, 87, 2630, 87, 2636, - - 87, 2631, 2637, 2632, 2639, 2633, 87, 2640, 2641, 2634, - 2642, 2644, 87, 87, 2635, 2645, 87, 87, 2643, 2646, - 87, 87, 2649, 4015, 87, 2647, 2636, 87, 2648, 87, - 2652, 2639, 2650, 4015, 2640, 2641, 2651, 2642, 2644, 4015, - 87, 87, 2645, 87, 2653, 2643, 2646, 2654, 87, 2649, - 2658, 2656, 2647, 87, 87, 2648, 2662, 2652, 87, 2650, - 2655, 2657, 87, 2651, 2659, 87, 2661, 2660, 87, 87, - 4015, 2653, 87, 87, 2654, 2664, 2665, 2658, 2656, 2663, - 2670, 2666, 2667, 87, 87, 87, 2669, 2655, 2657, 87, - 2668, 2659, 87, 2661, 2660, 2677, 2674, 87, 2678, 2685, - - 87, 175, 87, 2665, 2671, 87, 2663, 2670, 2666, 2667, - 2672, 87, 87, 2669, 2675, 2679, 2680, 2668, 87, 2676, - 2683, 2681, 2682, 2674, 87, 2684, 87, 87, 87, 87, - 87, 2671, 2690, 2689, 87, 87, 2686, 2672, 2691, 87, - 2692, 2695, 2679, 2680, 2693, 2694, 87, 2683, 2681, 2682, - 2687, 87, 2684, 87, 2699, 87, 2696, 2698, 2700, 87, - 2689, 2688, 87, 2686, 87, 2691, 87, 2692, 87, 2697, - 2701, 2693, 2694, 87, 2702, 2703, 87, 2687, 2705, 87, - 87, 2699, 2704, 2696, 2698, 87, 2706, 2709, 2688, 87, - 2708, 87, 87, 87, 2711, 2710, 2697, 2701, 87, 4015, - - 4015, 87, 2703, 87, 2712, 2705, 87, 87, 2707, 2704, - 87, 2713, 87, 2706, 2709, 2716, 2714, 2708, 2715, 2717, - 87, 2711, 2710, 2718, 87, 87, 87, 87, 2719, 2720, - 2721, 2712, 2723, 87, 2730, 2707, 2726, 87, 2713, 2722, - 2724, 87, 2716, 2714, 87, 2715, 2717, 2725, 87, 87, - 87, 87, 87, 2727, 2728, 2719, 2720, 2721, 2731, 2723, - 2729, 87, 87, 2726, 2732, 2733, 2722, 2724, 87, 87, - 2734, 4015, 87, 87, 2725, 87, 2737, 87, 87, 2735, - 2727, 2728, 2738, 87, 87, 2731, 2736, 2729, 87, 87, - 2739, 2732, 2733, 2740, 2741, 2743, 2742, 2734, 2744, 87, - - 4015, 2745, 4015, 2737, 2748, 87, 2735, 2750, 2746, 2738, - 87, 2747, 2749, 2736, 87, 87, 2753, 2739, 2751, 87, - 2740, 87, 2752, 2742, 2755, 2744, 87, 87, 2745, 87, - 87, 2748, 87, 2754, 87, 2746, 87, 87, 2747, 2749, - 87, 2756, 2758, 2753, 2757, 2751, 87, 2759, 2760, 2752, - 2761, 2755, 2762, 2763, 2766, 87, 2764, 4015, 2767, 2765, - 2754, 2768, 87, 2769, 87, 2772, 2773, 87, 2756, 87, - 87, 2757, 87, 87, 2759, 87, 2774, 2761, 2775, 2762, - 2763, 87, 87, 2764, 87, 2767, 2765, 2779, 2768, 87, - 2769, 2770, 87, 87, 2771, 2776, 2778, 2777, 87, 2780, - - 87, 87, 87, 2774, 87, 2775, 2781, 2782, 2783, 87, - 2784, 87, 2785, 2786, 2779, 87, 2787, 2788, 2770, 87, - 2789, 2771, 2776, 2778, 2777, 87, 87, 2791, 2790, 2792, - 4015, 2793, 2794, 87, 2782, 87, 87, 2784, 87, 87, - 2786, 87, 87, 2787, 87, 87, 2795, 87, 2796, 2798, - 2799, 2801, 2797, 2804, 2791, 2790, 2792, 87, 2793, 2794, - 87, 87, 2800, 2802, 2803, 4015, 2815, 2806, 2805, 2808, - 87, 87, 87, 87, 87, 2796, 2798, 87, 87, 2797, - 2804, 2811, 2807, 4015, 2814, 4015, 87, 2810, 2812, 2800, - 2802, 2803, 87, 87, 2806, 2805, 87, 2809, 87, 87, - - 87, 2817, 2813, 2818, 2819, 87, 87, 87, 2811, 2807, - 87, 87, 2816, 87, 2810, 2812, 87, 2820, 2821, 87, - 2823, 2825, 2830, 2826, 2809, 2822, 2827, 87, 2817, 2813, - 2818, 2819, 4015, 87, 2824, 2831, 4015, 2828, 87, 2816, - 87, 87, 87, 87, 2820, 87, 87, 2823, 2825, 87, - 2826, 2829, 2822, 2827, 2832, 2833, 2834, 2835, 2836, 2837, - 87, 2824, 2831, 87, 2828, 87, 87, 2838, 87, 2839, - 87, 2894, 2840, 2846, 87, 2844, 4015, 2845, 2829, 2847, - 4015, 2832, 2833, 2834, 2835, 2836, 2837, 87, 2841, 2848, - 4015, 4015, 87, 87, 2838, 87, 2839, 87, 87, 2840, - - 2846, 87, 2852, 2842, 2845, 2843, 2847, 87, 2849, 2850, - 87, 87, 87, 2851, 2858, 2841, 2848, 2853, 2859, 87, - 87, 2854, 87, 87, 2855, 2856, 87, 2857, 2860, 2852, - 2842, 2861, 2843, 2863, 2864, 2849, 2850, 87, 4015, 87, - 2851, 2858, 2865, 2862, 2853, 2870, 87, 87, 2854, 87, - 87, 2855, 2856, 2867, 2857, 87, 87, 2866, 2861, 87, - 87, 2864, 2868, 87, 87, 87, 2869, 87, 2875, 2865, - 2862, 4015, 2870, 87, 2871, 2874, 2872, 2873, 2876, 4015, - 2867, 2880, 2877, 2882, 2866, 2881, 87, 4015, 87, 2868, - 2878, 2879, 87, 2869, 87, 87, 4015, 87, 87, 87, - - 87, 2871, 2874, 2872, 2873, 87, 2883, 2885, 2880, 2877, - 87, 87, 2881, 2886, 2884, 87, 2888, 2878, 2879, 2887, - 4015, 4015, 2889, 87, 2890, 2892, 2891, 2896, 2893, 4015, - 2897, 87, 87, 2883, 2885, 2895, 87, 87, 87, 87, - 2886, 2884, 87, 2888, 175, 87, 2887, 87, 87, 2889, - 2898, 2890, 2892, 2891, 2896, 2893, 2899, 2897, 2900, 2901, - 2902, 2903, 2895, 4015, 2906, 2904, 2907, 2908, 2905, 87, - 87, 87, 87, 87, 2909, 2910, 87, 2898, 87, 2911, - 2916, 2912, 87, 2899, 87, 2900, 2901, 2902, 2903, 87, - 87, 2906, 2904, 2907, 2908, 2905, 2913, 2914, 2915, 2917, - - 2918, 87, 87, 2919, 4015, 4015, 87, 87, 2912, 2920, - 4015, 2921, 87, 2922, 4015, 2923, 2924, 2927, 87, 2926, - 87, 87, 87, 87, 2914, 2915, 2925, 2918, 87, 87, - 87, 87, 2929, 2930, 87, 2928, 2920, 87, 2921, 2931, - 2922, 87, 2923, 2924, 2932, 87, 2926, 2933, 87, 87, - 2934, 2937, 2935, 2925, 87, 2936, 87, 2938, 87, 2929, - 2930, 2939, 2928, 87, 2941, 2949, 2931, 2940, 2942, 87, - 87, 87, 87, 87, 2933, 87, 2943, 2934, 2937, 2935, - 87, 87, 2936, 87, 2938, 2944, 87, 2945, 87, 2947, - 2946, 2941, 87, 2948, 2940, 2942, 87, 87, 2950, 2952, - - 87, 2951, 2954, 2943, 2953, 4015, 2963, 2959, 2960, 2964, - 2955, 87, 2944, 87, 2945, 87, 2947, 2946, 87, 87, - 2948, 87, 2957, 87, 2956, 2950, 2952, 87, 2951, 2954, - 87, 2953, 87, 2958, 87, 2960, 2961, 2955, 87, 87, - 2962, 87, 2965, 2966, 87, 2968, 2967, 87, 2970, 2957, - 4015, 2956, 2969, 2971, 4015, 2972, 2979, 4015, 87, 2973, - 2958, 87, 87, 2961, 87, 87, 2974, 2962, 87, 2965, - 2966, 2975, 2968, 2967, 87, 2970, 2977, 87, 87, 2969, - 2971, 87, 2972, 87, 2976, 87, 2973, 2978, 87, 2980, - 2981, 2982, 4015, 2974, 2984, 87, 2985, 2983, 2975, 2986, - - 2988, 4015, 87, 2977, 87, 87, 2989, 87, 2990, 87, - 87, 2976, 87, 2995, 2978, 2996, 2980, 87, 2982, 87, - 2987, 87, 87, 2985, 2983, 4015, 2986, 2988, 2991, 2993, - 2992, 87, 2994, 2989, 87, 2990, 87, 87, 2997, 2998, - 87, 2999, 87, 4015, 3007, 3001, 87, 2987, 3005, 3000, - 87, 87, 3002, 3003, 87, 2991, 2993, 2992, 3004, 2994, - 87, 87, 3006, 87, 3014, 3009, 2998, 87, 2999, 3010, - 87, 87, 3001, 3008, 87, 3005, 3000, 87, 3011, 3002, - 3003, 3013, 87, 87, 87, 3004, 3012, 3015, 3016, 3006, - 87, 87, 3009, 87, 3017, 87, 3010, 3018, 3024, 3019, - - 3008, 3020, 3021, 3022, 4015, 87, 87, 87, 3013, 87, - 87, 3023, 87, 3012, 3015, 3016, 3027, 3025, 87, 3028, - 3029, 3017, 87, 3026, 3018, 87, 3019, 3030, 3020, 3021, - 3022, 3034, 87, 87, 87, 3031, 3032, 87, 3023, 87, - 3033, 3038, 87, 3027, 3025, 4015, 3028, 3029, 87, 87, - 3026, 3037, 87, 87, 3030, 87, 3040, 3035, 3034, 3036, - 3039, 3041, 3031, 3032, 87, 3042, 87, 3033, 87, 3044, - 3043, 3045, 87, 87, 3047, 4015, 3048, 3046, 3037, 3049, - 87, 4015, 3051, 87, 3035, 87, 3036, 3039, 87, 87, - 4015, 3056, 87, 3050, 87, 3052, 3044, 3043, 3045, 87, - - 87, 3047, 87, 3048, 3046, 87, 3049, 3053, 87, 3051, - 87, 3054, 3055, 3057, 87, 3058, 3059, 87, 87, 3060, - 3050, 87, 3052, 87, 3061, 3063, 3062, 3066, 4015, 3064, - 3065, 4015, 3069, 3071, 3053, 87, 4015, 87, 3054, 3055, - 3057, 87, 87, 87, 87, 87, 3060, 4015, 3067, 87, - 3070, 87, 3063, 3062, 3066, 87, 3064, 3065, 3068, 87, - 87, 3072, 87, 3073, 3074, 87, 3075, 3076, 87, 87, - 87, 3077, 3078, 4015, 3079, 3067, 3082, 3070, 87, 87, - 87, 3080, 3081, 3084, 3085, 3068, 3083, 87, 3072, 87, - 3073, 3074, 3090, 3075, 3076, 87, 87, 175, 3077, 3078, - - 3089, 3079, 87, 3082, 87, 3086, 87, 3087, 3080, 3081, - 3084, 3085, 87, 3083, 87, 3088, 3092, 3091, 3093, 87, - 87, 87, 87, 3096, 3094, 3095, 3097, 3089, 3099, 4015, - 3100, 87, 3086, 3098, 3087, 3101, 4015, 4015, 4015, 4015, - 87, 3119, 3088, 3092, 3091, 3093, 87, 87, 87, 3102, - 87, 3094, 3095, 87, 87, 3099, 87, 3100, 87, 3103, - 3098, 87, 3101, 3104, 3111, 3105, 3106, 3108, 87, 3107, - 3120, 87, 87, 87, 3109, 87, 3102, 87, 87, 3113, - 3110, 87, 87, 87, 3117, 4015, 3103, 87, 3112, 3118, - 3104, 3111, 3105, 3106, 3108, 87, 3107, 3120, 3114, 3115, - - 3116, 3109, 3122, 3123, 87, 87, 3113, 3110, 87, 87, - 87, 3117, 87, 3121, 3124, 3112, 3118, 3125, 87, 3126, - 87, 4015, 3127, 3129, 3128, 3114, 3115, 3116, 87, 3122, - 87, 87, 87, 87, 3135, 3130, 3131, 3138, 3137, 3132, - 3121, 3124, 3133, 87, 87, 87, 3126, 87, 87, 3127, - 3129, 3128, 3134, 87, 3136, 3139, 3143, 87, 87, 3141, - 87, 3135, 3130, 3131, 87, 3137, 3132, 3140, 87, 3133, - 3142, 3144, 3145, 4015, 87, 3146, 3147, 87, 3148, 3134, - 3149, 3136, 87, 87, 87, 87, 3141, 3150, 87, 3151, - 87, 87, 3152, 3156, 3140, 4015, 3157, 3142, 87, 3153, - - 87, 3154, 3146, 3147, 87, 3148, 87, 3149, 87, 87, - 3155, 87, 87, 3159, 3150, 3158, 3151, 87, 3160, 87, - 3156, 3161, 87, 3157, 3162, 3163, 3153, 3165, 3154, 3166, - 3164, 3167, 4015, 3170, 3169, 87, 3171, 3155, 87, 87, - 3159, 87, 3158, 87, 3168, 3160, 3172, 87, 87, 87, - 3173, 3162, 87, 87, 87, 87, 3166, 3164, 3167, 87, - 3170, 3169, 3174, 87, 3178, 3179, 3175, 3177, 3176, 87, - 3180, 3168, 87, 3172, 87, 87, 87, 3173, 3181, 3182, - 3183, 3185, 87, 3190, 4015, 3195, 3184, 87, 87, 3174, - 3186, 3178, 87, 3175, 3177, 3176, 87, 3180, 87, 3187, - - 3188, 3189, 87, 4015, 87, 3181, 87, 3183, 3185, 3191, - 87, 87, 87, 3184, 3197, 3192, 3193, 3186, 3196, 3194, - 3198, 87, 87, 87, 87, 87, 3187, 3188, 3189, 87, - 87, 87, 3200, 3199, 3201, 3202, 3191, 3204, 3205, 87, - 87, 3197, 3192, 3193, 3203, 3196, 3194, 3198, 3206, 87, - 3207, 3208, 3209, 87, 3211, 3210, 87, 3213, 4015, 87, - 3199, 3201, 3202, 87, 3204, 87, 87, 87, 3214, 87, - 87, 3203, 3215, 87, 87, 3206, 3212, 87, 3208, 3209, - 3217, 3211, 3210, 87, 87, 87, 3216, 3218, 3219, 3225, - 3222, 3220, 3221, 3223, 3224, 3214, 3228, 3227, 87, 3215, - - 4015, 4015, 87, 3212, 87, 87, 87, 3217, 87, 87, - 3229, 87, 87, 3216, 87, 3219, 87, 3222, 3220, 3221, - 3223, 3224, 3226, 87, 3227, 3230, 3231, 3233, 3232, 87, - 3234, 3237, 87, 3235, 3238, 4015, 4015, 3229, 87, 87, - 3236, 3239, 3241, 87, 3242, 4015, 87, 87, 3243, 3226, - 87, 87, 3230, 3231, 3233, 3232, 87, 3234, 3237, 87, - 3235, 3238, 3240, 87, 3244, 3245, 3247, 3236, 3239, 87, - 87, 87, 3246, 3249, 87, 3243, 87, 3248, 3252, 3250, - 87, 3251, 4015, 4015, 3259, 3253, 4015, 87, 87, 3240, - 87, 3244, 3245, 175, 3254, 87, 3255, 87, 3256, 3246, - - 3249, 3257, 3260, 3262, 3248, 3258, 3250, 87, 3251, 87, - 87, 87, 3253, 87, 3261, 3263, 87, 87, 3267, 3264, - 3269, 3254, 3268, 3255, 87, 3256, 3265, 87, 3257, 87, - 3262, 3266, 3258, 87, 3270, 3272, 87, 3271, 3274, 3278, - 87, 3261, 87, 87, 87, 3267, 3264, 3269, 3273, 3268, - 3276, 3275, 3279, 3277, 3280, 4015, 87, 87, 87, 87, - 87, 3282, 3272, 87, 3271, 3274, 87, 3281, 3284, 87, - 87, 87, 3283, 3285, 3286, 3273, 87, 3276, 3275, 3291, - 3277, 3280, 87, 3287, 87, 3288, 3289, 3290, 87, 87, - 87, 3292, 87, 87, 3281, 3284, 87, 87, 3293, 3283, - - 3285, 3286, 3294, 3295, 3296, 87, 3291, 87, 87, 87, - 3287, 3297, 3288, 3289, 3290, 3298, 87, 3299, 3292, 3300, - 3301, 87, 3306, 4015, 4015, 3293, 87, 87, 87, 3294, - 3295, 3296, 3302, 3307, 3309, 4015, 3310, 87, 3303, 3304, - 87, 87, 3298, 87, 3299, 87, 87, 3301, 3305, 87, - 3308, 87, 87, 87, 87, 3311, 87, 3312, 87, 3302, - 3307, 3309, 3313, 3310, 3314, 3303, 3304, 3315, 3320, 87, - 3316, 3317, 3318, 3319, 3322, 3305, 87, 3308, 87, 87, - 87, 87, 3311, 87, 3312, 3321, 3323, 87, 3327, 3313, - 3326, 3314, 3330, 3324, 87, 87, 87, 3316, 3317, 3318, - - 3319, 87, 3325, 3329, 3328, 87, 87, 3331, 3333, 3334, - 3332, 87, 3321, 4015, 87, 87, 3335, 3336, 87, 3330, - 3324, 3338, 87, 87, 87, 87, 87, 3340, 3337, 3325, - 3329, 3328, 3344, 87, 3331, 3339, 3334, 3332, 3341, 87, - 87, 87, 3342, 3335, 3336, 3346, 3345, 87, 87, 3343, - 87, 3347, 3348, 87, 3340, 3337, 4015, 3349, 87, 87, - 87, 3350, 3339, 3351, 87, 3341, 3352, 3353, 3359, 3342, - 3354, 3355, 87, 3345, 87, 87, 3343, 3356, 87, 87, - 87, 87, 3357, 87, 3349, 3358, 87, 3362, 3350, 3360, - 3351, 3363, 87, 87, 3353, 3359, 87, 3354, 3355, 3361, - - 87, 3364, 3365, 3366, 3369, 3367, 87, 3368, 3370, 87, - 3372, 3374, 3358, 87, 3362, 3371, 3360, 87, 87, 87, - 3373, 87, 87, 3376, 3375, 3377, 3361, 87, 87, 87, - 3366, 87, 3367, 3380, 3368, 3370, 87, 87, 87, 87, - 3378, 3379, 3371, 3381, 3386, 3385, 87, 3373, 3382, 87, - 87, 3375, 3377, 3383, 87, 3387, 3388, 3391, 3384, 3390, - 3393, 3389, 3394, 87, 87, 87, 3392, 3378, 3379, 87, - 87, 87, 3385, 87, 3395, 3382, 87, 87, 3396, 4015, - 3398, 87, 3387, 3491, 3391, 87, 3390, 3393, 87, 3397, - 3399, 87, 3400, 3392, 87, 3402, 3401, 3403, 3404, 4015, - - 87, 3406, 3405, 87, 4015, 4015, 87, 3398, 3411, 4015, - 87, 3409, 3414, 4015, 87, 87, 3397, 87, 87, 87, - 4015, 87, 3402, 3401, 3403, 3404, 87, 87, 3406, 3405, - 3407, 3408, 3410, 87, 3413, 87, 3412, 3415, 3409, 87, - 87, 87, 3418, 87, 3416, 3419, 3420, 87, 3426, 3421, - 87, 3423, 3417, 87, 3422, 87, 3424, 3407, 3408, 3410, - 3427, 3413, 3425, 3412, 3415, 87, 3428, 3436, 87, 3418, - 87, 3416, 3419, 3420, 3429, 87, 3430, 4015, 3431, 3417, - 3432, 87, 4015, 87, 3433, 87, 87, 3427, 3434, 3425, - 3437, 87, 87, 3428, 3436, 87, 3435, 87, 3439, 3438, - - 87, 3429, 87, 3430, 87, 3431, 87, 3432, 3440, 3441, - 87, 3433, 87, 3446, 3442, 3434, 87, 3437, 3447, 3448, - 87, 3443, 3444, 3435, 3450, 3439, 3438, 3445, 87, 87, - 3449, 87, 87, 3452, 87, 3440, 3441, 3451, 3453, 3454, - 87, 3442, 87, 87, 3456, 87, 3448, 87, 3443, 3444, - 3455, 87, 3457, 3458, 3445, 87, 3461, 3449, 87, 4015, - 3452, 3465, 3466, 3459, 3451, 3453, 87, 3460, 3462, 3463, - 87, 87, 4015, 3464, 87, 3467, 3469, 3455, 4015, 3457, - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 3459, 3468, 3470, 3471, 3460, 3462, 3463, 3472, 87, 3475, - - 3464, 3473, 3467, 3469, 87, 87, 3474, 3476, 87, 87, - 3477, 3478, 3479, 87, 3481, 3480, 3482, 3483, 3468, 3470, - 3471, 3484, 87, 87, 3472, 87, 3475, 87, 3488, 3486, - 87, 87, 3485, 87, 3476, 87, 87, 3477, 3478, 3479, - 3487, 3481, 3480, 87, 3483, 87, 3489, 3490, 87, 87, - 3493, 3492, 87, 3494, 3495, 87, 3486, 3496, 3497, 3485, - 3500, 3498, 3499, 4015, 87, 87, 87, 3487, 87, 3501, - 4015, 3502, 87, 87, 3490, 87, 87, 3493, 3492, 3505, - 3494, 3495, 87, 3503, 3496, 3504, 3506, 3500, 3498, 3499, - 87, 87, 87, 3511, 3507, 3512, 3501, 87, 3502, 3513, - - 3514, 87, 87, 3508, 4015, 4015, 3505, 87, 87, 4015, - 3503, 3509, 3504, 3506, 3510, 3517, 87, 3515, 87, 3523, - 87, 3507, 87, 87, 87, 3516, 87, 3514, 3518, 3519, - 3508, 3520, 87, 3525, 4015, 3521, 87, 87, 3509, 3522, - 3524, 3510, 3517, 3527, 3515, 3528, 87, 3526, 87, 87, - 3529, 87, 3516, 87, 87, 3518, 3519, 87, 3531, 3533, - 3525, 87, 3521, 87, 3532, 87, 3522, 3524, 3534, 3530, - 3527, 87, 3528, 3535, 3526, 3536, 3537, 3538, 3540, 3541, - 3576, 87, 87, 87, 3542, 87, 3533, 87, 87, 87, - 87, 3532, 3544, 87, 3539, 3534, 3530, 3548, 87, 87, - - 3535, 87, 3536, 3537, 3538, 87, 3541, 3545, 3543, 3546, - 3547, 3542, 87, 3551, 3554, 87, 87, 3549, 87, 3544, - 87, 3539, 87, 3550, 3548, 87, 3552, 3557, 87, 3553, - 87, 3558, 87, 87, 3545, 3543, 3546, 3547, 3555, 87, - 3551, 3554, 3556, 87, 3549, 3563, 3560, 87, 3562, 3559, - 3550, 3561, 3564, 3552, 87, 87, 3553, 87, 87, 3565, - 3567, 87, 3566, 3568, 3573, 3555, 87, 3578, 87, 3556, - 3569, 3570, 3563, 3571, 87, 3562, 3559, 3572, 87, 87, - 3579, 87, 3580, 3575, 87, 3574, 87, 87, 87, 3566, - 3568, 87, 87, 87, 87, 3587, 3586, 3569, 3570, 87, - - 3571, 87, 3577, 3581, 3572, 3582, 87, 3579, 87, 3580, - 3575, 87, 3574, 3583, 3584, 3585, 87, 3589, 3588, 87, - 3593, 3590, 87, 87, 87, 87, 3591, 87, 3594, 3577, - 3581, 87, 3582, 3592, 87, 3597, 3599, 3596, 3595, 3600, - 3583, 3584, 3585, 87, 87, 3588, 3604, 87, 3590, 87, - 87, 3601, 87, 3591, 3598, 87, 3602, 87, 87, 3603, - 3592, 87, 87, 3599, 3596, 3595, 3600, 87, 3605, 3606, - 3607, 3608, 3609, 3604, 4015, 87, 3610, 3611, 3601, 3612, - 4015, 3598, 3614, 3615, 87, 3616, 3603, 3613, 87, 87, - 87, 3617, 87, 3618, 3619, 3605, 87, 3607, 87, 3609, - - 87, 87, 87, 3610, 3611, 87, 3612, 87, 3620, 3614, - 3615, 3622, 3616, 3626, 3613, 3621, 3623, 3624, 87, 3625, - 87, 3619, 3629, 87, 87, 3627, 3628, 87, 3631, 3632, - 3634, 87, 3630, 87, 3633, 87, 3637, 87, 3622, 87, - 87, 3638, 3621, 87, 3624, 87, 3625, 87, 87, 87, - 3635, 3636, 3627, 3628, 87, 3631, 3632, 87, 87, 3630, - 3639, 3633, 87, 3637, 3640, 4015, 3641, 3642, 87, 3644, - 3643, 3645, 3646, 3652, 3649, 3648, 3650, 3635, 3636, 3654, - 87, 87, 3647, 3651, 87, 3653, 3656, 87, 87, 3657, - 87, 87, 87, 3641, 3642, 4015, 87, 3643, 87, 87, - - 87, 87, 3648, 3650, 3655, 87, 87, 87, 3663, 3647, - 3651, 3658, 3653, 87, 3664, 87, 87, 3659, 3660, 87, - 3661, 3662, 87, 87, 3665, 87, 87, 3667, 87, 3666, - 3670, 3655, 3668, 3676, 87, 3663, 3671, 87, 3658, 87, - 87, 87, 3669, 87, 3659, 3660, 3672, 3661, 3662, 3673, - 3678, 3665, 3674, 87, 3667, 3675, 3666, 87, 87, 3668, - 87, 3677, 3679, 3671, 87, 87, 3681, 3682, 87, 3669, - 3680, 3683, 87, 3672, 3684, 87, 87, 3678, 3685, 3674, - 3686, 3688, 3675, 3689, 87, 4015, 3692, 3687, 3677, 3679, - 4015, 87, 87, 3681, 87, 3690, 87, 3680, 87, 3691, - - 87, 3684, 87, 3693, 3694, 3685, 87, 3696, 3688, 87, - 87, 87, 87, 3692, 3687, 3699, 3695, 87, 3697, 3700, - 3698, 4015, 3690, 87, 87, 87, 3691, 3706, 3702, 87, - 3693, 3694, 3701, 87, 3696, 87, 87, 3703, 87, 3710, - 87, 3704, 3699, 3695, 87, 3697, 3700, 3698, 87, 3705, - 3709, 87, 3707, 3708, 3706, 3702, 87, 3713, 87, 3701, - 3711, 87, 87, 3712, 3703, 3715, 3710, 3717, 3704, 3714, - 87, 3716, 87, 3718, 3719, 3723, 3705, 3709, 3726, 3707, - 3708, 87, 87, 3720, 3728, 3721, 3722, 3711, 4015, 87, - 3712, 87, 3715, 3724, 3717, 87, 3714, 87, 3716, 3725, - - 87, 87, 87, 3733, 3727, 87, 87, 87, 87, 3736, - 3720, 87, 3721, 3722, 3739, 87, 87, 3729, 3730, 4015, - 3724, 3731, 3732, 3734, 3735, 4015, 3725, 3737, 3740, 3738, - 87, 3727, 87, 3742, 3743, 3741, 3736, 87, 3744, 4015, - 3745, 87, 3749, 4015, 3746, 4015, 87, 87, 87, 87, - 87, 87, 87, 3748, 3737, 3740, 3738, 3747, 3753, 3750, - 87, 87, 3741, 3751, 87, 87, 87, 3745, 87, 87, - 87, 3746, 3752, 3754, 87, 87, 3755, 3756, 87, 3757, - 3748, 3760, 3758, 3759, 3747, 3753, 3750, 3762, 87, 87, - 3751, 3763, 3764, 3761, 87, 3765, 87, 3766, 3773, 3752, - - 3754, 3768, 87, 3755, 3756, 87, 3757, 87, 87, 3758, - 3759, 87, 3777, 87, 3762, 3767, 3771, 4015, 87, 87, - 3761, 3772, 87, 87, 3766, 3775, 3769, 87, 3768, 3770, - 87, 3774, 3776, 87, 87, 3778, 3780, 87, 87, 3777, - 3781, 3779, 3767, 3782, 87, 4015, 3783, 3784, 87, 87, - 4015, 3787, 3775, 3769, 3785, 3786, 3770, 87, 3774, 3776, - 3789, 3790, 3778, 87, 87, 3791, 87, 3788, 3779, 3793, - 3782, 3794, 87, 87, 87, 3792, 3795, 87, 87, 3796, - 87, 3785, 3786, 87, 87, 3797, 3798, 87, 87, 3799, - 3800, 3802, 3791, 3803, 3788, 3804, 87, 3805, 87, 3801, - - 87, 3807, 3792, 87, 3806, 3809, 87, 3811, 87, 87, - 4015, 3808, 87, 87, 4015, 87, 87, 87, 3802, 87, - 87, 3810, 87, 87, 3805, 3812, 3801, 3813, 3807, 87, - 3814, 3806, 87, 3815, 87, 3816, 3817, 87, 3808, 3818, - 3819, 87, 3820, 4015, 3821, 87, 3822, 3827, 3810, 3824, - 87, 87, 3812, 87, 3813, 3823, 87, 3814, 4015, 87, - 3815, 3826, 3816, 87, 87, 3825, 3818, 87, 3828, 3820, - 87, 3821, 3829, 3822, 87, 87, 3824, 4015, 3830, 87, - 3831, 87, 3823, 3833, 3834, 87, 87, 3832, 3826, 87, - 3835, 3836, 3825, 3837, 87, 3828, 3838, 87, 87, 3829, - - 3840, 3839, 87, 87, 87, 3830, 3841, 3831, 87, 3843, - 3833, 3834, 3842, 87, 3832, 3844, 3845, 3835, 3836, 87, - 3837, 3846, 87, 3838, 3849, 3847, 87, 3840, 3839, 87, - 87, 3848, 3851, 3841, 3850, 3853, 87, 3852, 3855, 3842, - 4015, 87, 87, 87, 87, 3857, 3856, 87, 87, 87, - 87, 3849, 3847, 3854, 87, 3859, 4015, 87, 3848, 3851, - 3862, 3850, 3858, 3860, 3852, 3855, 3866, 87, 87, 87, - 87, 3861, 3857, 3856, 87, 3863, 3864, 87, 87, 87, - 3854, 87, 3859, 3865, 87, 3867, 87, 3862, 3869, 3858, - 3860, 3868, 3870, 3866, 87, 87, 3872, 3873, 3861, 3871, - - 87, 3874, 3863, 3864, 87, 3875, 3878, 87, 87, 3876, - 3865, 3879, 3867, 87, 3881, 3869, 3880, 3882, 3868, 3870, - 3883, 87, 87, 3872, 87, 3884, 3871, 87, 3874, 87, - 3877, 3885, 3875, 87, 3886, 3888, 3876, 87, 3879, 87, - 87, 87, 87, 3880, 3882, 3889, 87, 3883, 3887, 3890, - 3893, 3891, 87, 87, 3892, 87, 3894, 3877, 87, 87, - 3897, 3886, 3888, 3896, 3895, 3899, 87, 87, 3900, 87, - 3898, 87, 3889, 3901, 3902, 3887, 3890, 87, 3891, 87, - 3904, 3892, 87, 3894, 3903, 87, 3905, 87, 87, 3909, - 3896, 3895, 87, 3906, 3907, 87, 87, 3898, 87, 3908, - - 87, 87, 87, 3910, 3912, 87, 3911, 3904, 3914, 3913, - 87, 3903, 3915, 87, 3916, 3917, 3909, 87, 3920, 4015, - 3906, 3907, 3921, 87, 3919, 3924, 3908, 87, 3922, 87, - 87, 3912, 87, 3911, 87, 3918, 3913, 3925, 87, 3926, - 87, 3916, 3917, 87, 87, 87, 87, 3923, 3927, 87, - 87, 3919, 3924, 3928, 87, 3922, 3929, 3930, 3931, 3932, - 87, 3933, 3918, 4015, 87, 87, 3926, 3934, 3935, 87, - 3936, 87, 87, 87, 3923, 3927, 3941, 3943, 87, 3942, - 3928, 3940, 4015, 3929, 3930, 3931, 3932, 3938, 3933, 87, - 87, 3937, 3939, 3945, 3934, 3935, 87, 87, 87, 87, - - 87, 87, 3944, 87, 3946, 3947, 3942, 3949, 3940, 87, - 3950, 3951, 4015, 3948, 3938, 87, 3952, 4015, 3937, 3939, - 3945, 87, 3954, 4015, 3959, 3953, 87, 87, 87, 3944, - 3956, 3946, 3947, 87, 87, 4015, 3955, 87, 3951, 87, - 3948, 3962, 3963, 87, 87, 87, 3957, 3958, 3961, 3954, - 87, 3960, 3953, 3964, 87, 87, 87, 3956, 3965, 87, - 3967, 3966, 87, 3955, 87, 3971, 4015, 87, 3962, 3963, - 3970, 3968, 3972, 3957, 3958, 3961, 87, 3976, 3960, 87, - 87, 3969, 87, 3974, 87, 3965, 3973, 3967, 3966, 87, - 3978, 87, 3971, 3977, 87, 3975, 87, 3970, 3968, 3972, - - 87, 87, 3979, 87, 3976, 3980, 87, 3982, 3969, 3983, - 3974, 3981, 3984, 3973, 3987, 87, 87, 3978, 3985, 3986, - 3977, 4015, 3975, 3988, 3993, 4015, 4015, 87, 87, 3979, - 3991, 87, 3980, 3989, 3982, 4015, 87, 3995, 3981, 87, - 87, 87, 4015, 87, 87, 3985, 3986, 3990, 3992, 3996, - 3988, 87, 87, 87, 3994, 87, 87, 3991, 3997, 87, - 3989, 3998, 87, 3999, 3995, 4000, 87, 4003, 4004, 87, - 4001, 87, 4002, 4006, 3990, 3992, 3996, 4007, 87, 4009, - 87, 3994, 4005, 4008, 4015, 3997, 4010, 4013, 3998, 87, - 3999, 4014, 87, 87, 4003, 87, 4015, 4001, 4015, 4002, - - 87, 87, 87, 87, 87, 4015, 4009, 4011, 87, 4005, - 4008, 4012, 4015, 4010, 87, 87, 4015, 4015, 87, 87, - 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, - 4015, 4015, 4015, 4015, 4011, 4015, 4015, 4015, 4012, 48, - 48, 48, 48, 48, 48, 48, 53, 53, 53, 53, - 53, 53, 53, 58, 58, 58, 58, 58, 58, 58, - 64, 64, 64, 64, 64, 64, 64, 69, 69, 69, - 69, 69, 69, 69, 75, 75, 75, 75, 75, 75, - 75, 81, 81, 81, 81, 81, 81, 81, 90, 90, - 4015, 90, 90, 90, 90, 165, 165, 4015, 4015, 4015, - - 165, 165, 167, 167, 4015, 4015, 167, 4015, 167, 169, - 4015, 4015, 4015, 4015, 4015, 169, 172, 172, 4015, 4015, - 4015, 172, 172, 174, 4015, 4015, 4015, 4015, 4015, 174, - 176, 176, 4015, 176, 176, 176, 176, 179, 4015, 4015, - 4015, 4015, 4015, 179, 182, 182, 4015, 4015, 4015, 182, - 182, 91, 91, 4015, 91, 91, 91, 91, 17, 4015, - 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, - 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, - 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, - 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, - - 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, - 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, - 4015, 4015, 4015, 4015, 4015 + 87, 4117, 306, 177, 291, 87, 295, 289, 296, 297, + 87, 300, 298, 293, 87, 319, 303, 87, 320, 299, + 294, 301, 304, 305, 87, 87, 302, 310, 307, 306, + 308, 311, 321, 87, 324, 312, 323, 322, 325, 327, + 328, 87, 319, 326, 87, 320, 87, 1049, 87, 304, + 305, 330, 313, 826, 87, 307, 87, 308, 87, 87, + + 87, 324, 312, 323, 87, 325, 327, 331, 329, 4117, + 326, 332, 87, 333, 87, 334, 87, 362, 330, 313, + 314, 87, 87, 337, 338, 315, 87, 87, 4117, 87, + 316, 339, 87, 345, 331, 329, 317, 318, 332, 346, + 333, 335, 334, 87, 336, 4117, 87, 314, 87, 87, + 337, 338, 315, 87, 347, 87, 87, 316, 339, 348, + 345, 87, 4117, 317, 318, 351, 346, 350, 335, 356, + 87, 336, 340, 354, 364, 341, 352, 342, 358, 4117, + 87, 347, 367, 357, 87, 360, 348, 4117, 363, 343, + 4117, 344, 4117, 87, 350, 368, 369, 87, 87, 340, + + 354, 87, 341, 352, 342, 358, 87, 87, 365, 87, + 357, 87, 360, 366, 87, 363, 343, 87, 344, 370, + 371, 374, 368, 369, 87, 372, 87, 377, 376, 4117, + 375, 378, 379, 87, 373, 365, 382, 4117, 389, 87, + 366, 87, 87, 87, 380, 385, 370, 371, 374, 87, + 87, 87, 372, 87, 377, 376, 87, 375, 378, 379, + 383, 373, 381, 382, 387, 384, 386, 87, 392, 388, + 87, 380, 385, 87, 87, 87, 390, 391, 393, 394, + 395, 398, 397, 4117, 87, 87, 87, 87, 396, 381, + 87, 387, 87, 386, 399, 392, 388, 400, 402, 407, + + 406, 87, 87, 390, 391, 403, 394, 395, 398, 397, + 87, 401, 404, 87, 405, 396, 409, 410, 4117, 87, + 87, 4117, 408, 414, 412, 87, 87, 87, 87, 87, + 87, 87, 403, 422, 411, 419, 413, 415, 401, 404, + 87, 405, 87, 87, 410, 87, 416, 417, 87, 408, + 414, 412, 175, 418, 87, 420, 421, 87, 423, 87, + 87, 411, 419, 413, 415, 87, 87, 424, 426, 425, + 429, 4117, 427, 416, 417, 428, 434, 430, 87, 87, + 418, 4117, 420, 421, 87, 431, 432, 435, 87, 87, + 87, 87, 436, 439, 424, 87, 425, 429, 87, 427, + + 87, 433, 428, 87, 430, 87, 437, 441, 87, 438, + 452, 87, 431, 432, 435, 87, 87, 87, 442, 436, + 439, 443, 447, 4117, 445, 4117, 444, 454, 433, 448, + 4117, 456, 87, 437, 441, 87, 438, 87, 446, 449, + 450, 461, 87, 459, 87, 442, 87, 87, 443, 447, + 87, 445, 87, 444, 451, 453, 448, 87, 87, 87, + 455, 457, 87, 87, 460, 446, 449, 450, 87, 87, + 459, 462, 464, 87, 465, 467, 4117, 4117, 458, 87, + 468, 451, 453, 87, 87, 87, 87, 455, 457, 87, + 466, 460, 469, 478, 4117, 463, 87, 471, 4117, 464, + + 470, 465, 467, 87, 472, 458, 87, 468, 474, 87, + 4117, 479, 87, 480, 473, 476, 87, 466, 525, 469, + 87, 475, 463, 87, 471, 87, 87, 470, 481, 482, + 87, 472, 477, 4117, 87, 474, 490, 491, 479, 87, + 492, 473, 476, 501, 87, 87, 87, 4117, 475, 530, + 87, 502, 87, 500, 87, 481, 482, 87, 508, 477, + 483, 509, 87, 490, 491, 484, 87, 492, 485, 4117, + 501, 503, 504, 486, 487, 488, 489, 87, 502, 505, + 500, 87, 87, 87, 506, 508, 4117, 483, 87, 518, + 4117, 4117, 484, 4117, 516, 485, 87, 512, 503, 504, + + 486, 487, 488, 489, 493, 517, 494, 510, 495, 87, + 511, 87, 87, 513, 4117, 520, 87, 87, 496, 497, + 498, 516, 499, 87, 512, 87, 514, 515, 87, 519, + 524, 493, 517, 494, 510, 495, 87, 511, 521, 4117, + 513, 87, 520, 523, 526, 496, 497, 498, 522, 499, + 87, 87, 87, 514, 515, 87, 519, 524, 527, 87, + 528, 529, 535, 537, 87, 521, 87, 87, 4117, 87, + 523, 526, 531, 87, 532, 522, 549, 4117, 536, 4117, + 538, 4117, 541, 533, 542, 527, 539, 528, 529, 535, + 534, 543, 540, 544, 87, 87, 550, 551, 87, 531, + + 87, 532, 87, 549, 87, 536, 87, 538, 87, 541, + 533, 542, 552, 539, 545, 553, 567, 534, 543, 540, + 571, 566, 87, 550, 569, 87, 585, 546, 87, 87, + 547, 586, 548, 87, 568, 4117, 87, 87, 87, 87, + 87, 545, 553, 567, 570, 4117, 587, 571, 566, 572, + 4117, 569, 4117, 4117, 546, 583, 87, 547, 87, 548, + 554, 568, 555, 584, 4117, 573, 574, 87, 556, 590, + 4117, 570, 557, 87, 596, 175, 572, 558, 87, 87, + 559, 87, 583, 87, 588, 592, 87, 554, 593, 555, + 584, 589, 573, 574, 591, 556, 590, 87, 659, 557, + + 595, 596, 87, 4117, 558, 87, 87, 559, 560, 594, + 561, 588, 592, 597, 87, 593, 599, 87, 589, 87, + 598, 591, 610, 562, 600, 659, 563, 87, 564, 87, + 565, 617, 87, 601, 87, 560, 594, 561, 604, 605, + 597, 4117, 4117, 599, 4117, 87, 87, 598, 4117, 606, + 562, 607, 608, 563, 87, 564, 87, 565, 575, 576, + 601, 87, 602, 87, 611, 604, 605, 4117, 577, 578, + 579, 580, 581, 87, 87, 582, 606, 613, 607, 608, + 603, 609, 4117, 87, 87, 575, 576, 612, 615, 602, + 87, 611, 87, 87, 87, 577, 578, 579, 580, 581, + + 614, 87, 582, 616, 613, 619, 620, 603, 609, 87, + 625, 618, 87, 87, 612, 615, 87, 621, 622, 4117, + 628, 87, 623, 626, 624, 633, 627, 614, 87, 87, + 616, 87, 619, 620, 87, 629, 4117, 625, 618, 87, + 630, 631, 4117, 4117, 636, 87, 87, 628, 87, 623, + 626, 624, 633, 627, 634, 637, 4117, 87, 632, 4117, + 638, 4117, 629, 87, 639, 87, 641, 630, 631, 635, + 87, 636, 87, 652, 640, 87, 653, 87, 657, 87, + 671, 634, 637, 87, 654, 632, 655, 638, 642, 643, + 656, 639, 658, 641, 87, 660, 635, 661, 87, 4117, + + 644, 640, 645, 653, 662, 87, 87, 87, 87, 87, + 87, 654, 87, 655, 664, 642, 643, 656, 87, 658, + 665, 87, 660, 666, 661, 4117, 87, 644, 663, 645, + 646, 662, 668, 673, 87, 87, 667, 669, 647, 648, + 87, 664, 649, 650, 87, 670, 651, 665, 4117, 674, + 87, 87, 87, 672, 87, 663, 87, 646, 4117, 668, + 673, 87, 675, 667, 669, 647, 648, 680, 87, 649, + 650, 87, 670, 651, 676, 87, 674, 677, 4117, 678, + 672, 681, 87, 682, 686, 683, 4117, 679, 87, 675, + 87, 684, 87, 689, 680, 687, 87, 688, 685, 87, + + 87, 676, 691, 693, 677, 87, 678, 694, 681, 87, + 682, 686, 683, 87, 679, 87, 87, 87, 684, 87, + 689, 690, 687, 692, 688, 685, 695, 696, 87, 691, + 693, 87, 4117, 87, 694, 697, 87, 698, 699, 4117, + 700, 702, 701, 87, 703, 87, 87, 87, 690, 704, + 692, 709, 4117, 695, 710, 705, 87, 87, 87, 87, + 87, 87, 697, 712, 698, 699, 87, 700, 702, 701, + 87, 703, 706, 716, 707, 708, 704, 711, 709, 715, + 713, 87, 705, 714, 87, 718, 87, 717, 4117, 719, + 87, 87, 720, 721, 725, 87, 4117, 87, 87, 706, + + 722, 707, 708, 723, 711, 87, 715, 713, 87, 87, + 714, 724, 718, 87, 717, 87, 719, 87, 726, 720, + 721, 728, 727, 730, 734, 87, 87, 722, 732, 87, + 723, 733, 731, 87, 736, 738, 87, 87, 724, 771, + 4117, 4117, 735, 87, 729, 726, 87, 87, 737, 727, + 730, 734, 87, 87, 87, 732, 87, 87, 733, 731, + 87, 736, 738, 739, 740, 741, 771, 751, 752, 735, + 750, 729, 87, 87, 87, 737, 753, 87, 754, 87, + 87, 791, 755, 796, 4117, 805, 87, 757, 4117, 760, + 739, 740, 741, 742, 751, 752, 756, 750, 743, 87, + + 744, 87, 4117, 753, 87, 754, 745, 87, 746, 755, + 87, 747, 748, 87, 757, 87, 760, 87, 749, 87, + 742, 761, 758, 756, 765, 743, 759, 744, 4117, 763, + 770, 4117, 764, 745, 768, 746, 4117, 766, 747, 748, + 87, 762, 87, 87, 87, 749, 87, 767, 761, 758, + 773, 765, 769, 759, 87, 772, 763, 770, 774, 764, + 87, 768, 87, 87, 775, 777, 776, 780, 762, 87, + 779, 778, 4117, 782, 767, 87, 87, 773, 87, 769, + 87, 781, 772, 87, 783, 774, 87, 788, 786, 785, + 87, 775, 777, 776, 780, 87, 87, 779, 778, 784, + + 782, 87, 87, 787, 789, 87, 790, 87, 781, 87, + 792, 783, 793, 794, 788, 786, 785, 4117, 87, 795, + 799, 87, 797, 801, 87, 87, 784, 87, 800, 175, + 787, 789, 87, 790, 87, 798, 804, 792, 802, 793, + 794, 87, 87, 87, 87, 803, 795, 799, 87, 797, + 801, 806, 807, 808, 809, 800, 810, 4117, 4117, 812, + 811, 816, 798, 87, 87, 802, 87, 813, 814, 87, + 87, 87, 803, 87, 815, 824, 825, 4117, 806, 827, + 87, 809, 820, 810, 87, 87, 812, 811, 816, 87, + 817, 87, 823, 87, 813, 814, 828, 818, 87, 821, + + 819, 815, 87, 87, 822, 829, 87, 830, 87, 820, + 831, 87, 4117, 833, 834, 832, 837, 817, 835, 823, + 87, 838, 87, 87, 818, 836, 840, 819, 839, 87, + 845, 87, 87, 87, 841, 4117, 843, 844, 87, 87, + 833, 834, 87, 837, 87, 835, 847, 87, 838, 87, + 87, 851, 836, 840, 842, 839, 87, 849, 87, 846, + 87, 841, 87, 843, 844, 848, 87, 850, 854, 87, + 852, 4117, 858, 847, 87, 860, 856, 87, 851, 87, + 87, 842, 87, 853, 849, 855, 846, 87, 87, 87, + 87, 857, 848, 87, 850, 854, 866, 852, 87, 859, + + 861, 872, 860, 856, 87, 862, 865, 867, 863, 864, + 853, 4117, 855, 87, 868, 87, 87, 869, 857, 874, + 870, 87, 87, 866, 87, 87, 859, 861, 872, 873, + 871, 875, 862, 865, 867, 863, 864, 876, 879, 87, + 877, 868, 87, 87, 869, 881, 87, 870, 880, 87, + 884, 87, 882, 87, 886, 883, 873, 871, 875, 87, + 885, 87, 878, 87, 876, 879, 87, 877, 87, 87, + 87, 887, 881, 889, 87, 880, 888, 884, 890, 882, + 87, 886, 883, 87, 891, 892, 893, 885, 894, 878, + 896, 895, 87, 87, 87, 898, 87, 87, 887, 899, + + 87, 87, 897, 888, 87, 890, 900, 912, 87, 4117, + 87, 891, 892, 893, 901, 894, 905, 896, 895, 904, + 87, 4117, 898, 902, 903, 4117, 906, 87, 907, 897, + 87, 87, 908, 900, 909, 910, 911, 87, 87, 87, + 87, 901, 913, 905, 87, 87, 904, 87, 87, 914, + 915, 917, 87, 906, 4117, 907, 916, 87, 87, 908, + 918, 909, 910, 911, 87, 919, 921, 922, 923, 913, + 920, 87, 931, 87, 87, 924, 4117, 915, 917, 87, + 87, 87, 932, 916, 935, 941, 87, 918, 933, 87, + 87, 87, 958, 921, 922, 923, 936, 87, 4117, 934, + + 4117, 4117, 924, 925, 87, 926, 87, 4117, 937, 932, + 939, 935, 927, 938, 942, 933, 947, 87, 928, 929, + 930, 87, 87, 936, 87, 940, 934, 87, 87, 87, + 925, 945, 926, 87, 87, 937, 946, 939, 943, 927, + 938, 942, 87, 947, 949, 928, 929, 930, 944, 948, + 950, 87, 940, 951, 956, 952, 959, 953, 87, 954, + 87, 87, 87, 87, 955, 943, 87, 957, 87, 87, + 960, 949, 4117, 87, 87, 944, 948, 950, 87, 87, + 951, 956, 952, 959, 953, 4117, 954, 961, 87, 962, + 964, 955, 968, 963, 957, 965, 967, 960, 87, 87, + + 969, 87, 87, 972, 966, 970, 971, 87, 87, 973, + 4117, 87, 975, 4117, 961, 87, 962, 964, 87, 87, + 963, 87, 965, 967, 87, 1008, 974, 969, 976, 977, + 972, 966, 970, 971, 87, 87, 973, 87, 978, 975, + 87, 979, 980, 981, 982, 983, 984, 87, 985, 987, + 87, 87, 87, 974, 986, 976, 977, 87, 988, 87, + 991, 4117, 87, 989, 4117, 978, 87, 87, 979, 980, + 981, 982, 983, 984, 87, 985, 987, 87, 990, 87, + 993, 986, 87, 992, 994, 988, 995, 991, 87, 997, + 989, 87, 996, 998, 87, 999, 87, 4117, 87, 1000, + + 1003, 1018, 1004, 1001, 1002, 990, 87, 993, 1097, 87, + 992, 994, 87, 995, 87, 87, 997, 87, 87, 996, + 998, 87, 999, 1005, 87, 1006, 1000, 1003, 87, 1004, + 1001, 1002, 1007, 1009, 1010, 87, 1012, 4117, 1013, 1011, + 1015, 87, 1014, 87, 1016, 1017, 1026, 87, 1021, 87, + 1005, 87, 1006, 1022, 87, 175, 87, 87, 87, 1007, + 1009, 1010, 87, 1012, 87, 1013, 1011, 1015, 1019, 1014, + 1023, 1016, 1017, 1024, 1025, 1027, 1020, 1028, 87, 1031, + 87, 87, 87, 87, 87, 1029, 1033, 1032, 1034, 1037, + 1030, 87, 87, 4117, 87, 1019, 87, 1023, 1036, 1064, + + 1024, 1025, 1027, 1020, 1028, 87, 1031, 1035, 87, 87, + 87, 1114, 1029, 1038, 1032, 1048, 1037, 1030, 87, 1039, + 87, 87, 87, 1040, 4117, 1036, 87, 87, 1050, 1051, + 87, 87, 1052, 4117, 1035, 1061, 1053, 1056, 87, 1054, + 1038, 87, 1048, 87, 87, 1116, 1039, 87, 87, 4117, + 1040, 1041, 1055, 87, 1042, 1050, 1051, 1057, 1043, 1052, + 87, 1044, 1061, 1053, 1056, 1058, 1054, 1059, 1045, 1046, + 87, 1047, 87, 1060, 1062, 1063, 87, 4117, 1041, 1055, + 87, 1042, 87, 1073, 1057, 1043, 1074, 87, 1044, 87, + 87, 87, 1058, 87, 1059, 1045, 1046, 1081, 1047, 1075, + + 1060, 1062, 1063, 1065, 1066, 87, 1067, 1076, 87, 1068, + 1073, 4117, 1077, 1074, 1069, 1078, 87, 1082, 87, 87, + 1070, 1071, 1079, 1072, 1081, 87, 1075, 4117, 1084, 87, + 1065, 1066, 1083, 1067, 1076, 87, 1068, 1086, 1080, 1077, + 87, 1069, 1078, 1089, 1082, 87, 1090, 1070, 1071, 1079, + 1072, 1085, 1087, 87, 87, 1084, 1091, 1088, 1092, 1083, + 1093, 87, 1099, 87, 1086, 1080, 1094, 1095, 87, 4117, + 1089, 1100, 87, 1090, 1096, 1098, 1101, 87, 1085, 87, + 87, 1102, 4117, 1091, 87, 1092, 87, 1093, 87, 1099, + 87, 87, 1105, 1094, 1095, 1106, 87, 1103, 1100, 87, + + 87, 1096, 1098, 1101, 87, 1104, 1107, 1108, 1102, 1110, + 1109, 87, 1112, 87, 87, 1113, 1111, 1120, 87, 1105, + 87, 87, 1106, 87, 1103, 87, 1115, 87, 1119, 1121, + 1125, 4117, 1104, 1107, 1108, 87, 1110, 1109, 1122, 1112, + 1117, 1126, 1113, 1111, 1123, 1118, 1128, 87, 87, 87, + 87, 1124, 87, 1115, 87, 1119, 1121, 1127, 87, 1129, + 1130, 1131, 87, 87, 1132, 1122, 1133, 1137, 1126, 4117, + 87, 1123, 87, 1128, 1135, 87, 1134, 1136, 1124, 87, + 87, 1140, 1138, 87, 1142, 1145, 1129, 1130, 87, 87, + 87, 87, 87, 1133, 1137, 87, 1139, 1143, 1141, 87, + + 1144, 1135, 87, 1134, 1136, 87, 87, 1146, 1140, 1138, + 1148, 87, 87, 1147, 1149, 87, 1152, 1150, 87, 87, + 1151, 87, 87, 1139, 1143, 1141, 87, 1144, 1154, 1156, + 1153, 87, 87, 1155, 87, 1158, 1157, 1148, 4117, 87, + 1147, 1149, 87, 1152, 1150, 87, 1159, 1151, 1161, 1160, + 1162, 87, 87, 87, 1163, 1154, 1156, 1153, 87, 1168, + 1155, 87, 1158, 1157, 1164, 1171, 1167, 4117, 1169, 1165, + 87, 87, 87, 1159, 1166, 1161, 1160, 1162, 87, 87, + 87, 1163, 1170, 87, 1172, 87, 1168, 87, 1173, 1176, + 87, 1164, 1171, 1167, 1174, 1169, 1177, 87, 1178, 1180, + + 1179, 87, 1175, 1182, 87, 87, 1181, 4117, 1184, 1170, + 87, 1172, 1183, 87, 87, 1173, 1176, 1185, 87, 87, + 1186, 1174, 87, 87, 87, 1178, 1180, 1179, 87, 1175, + 1182, 1188, 1187, 1181, 1189, 1184, 87, 1190, 87, 1183, + 1191, 1193, 1192, 87, 1185, 87, 1194, 1186, 1198, 1196, + 1197, 1201, 1199, 1212, 87, 1195, 87, 87, 1188, 1187, + 87, 1189, 87, 87, 1190, 87, 1200, 87, 1193, 1192, + 4117, 87, 87, 1194, 1204, 1198, 1196, 1197, 87, 1199, + 1203, 1202, 1195, 1205, 1206, 87, 4117, 87, 87, 87, + 87, 1207, 87, 1200, 1208, 1210, 1209, 1213, 87, 87, + + 1214, 1204, 87, 87, 87, 1211, 1215, 1203, 1202, 1217, + 1205, 1206, 87, 87, 1218, 1216, 87, 1219, 1207, 4117, + 1220, 1208, 1210, 1209, 1225, 1221, 1222, 1214, 87, 87, + 87, 1229, 1211, 87, 1223, 1224, 1217, 1226, 87, 1227, + 1228, 87, 1216, 87, 1232, 4117, 87, 1220, 1234, 87, + 1230, 1225, 1221, 1222, 1231, 87, 1235, 87, 1229, 87, + 1233, 1223, 1224, 87, 1226, 87, 1236, 87, 87, 1237, + 1298, 87, 87, 1238, 1241, 87, 87, 1230, 1243, 1242, + 87, 1231, 1245, 1235, 1244, 1247, 1239, 1233, 1240, 1246, + 87, 87, 87, 1236, 87, 1249, 1237, 87, 1248, 4117, + + 1238, 1251, 87, 4117, 87, 1243, 175, 87, 87, 1245, + 87, 1244, 1247, 1239, 1252, 1240, 1246, 87, 1250, 1253, + 1255, 1266, 1249, 1257, 1256, 1248, 87, 87, 1251, 87, + 1254, 87, 1264, 4117, 87, 1265, 1268, 4117, 4117, 4117, + 1267, 1252, 1299, 87, 87, 1250, 1253, 1255, 1266, 4117, + 1257, 1256, 87, 1269, 87, 87, 1274, 1254, 1258, 1264, + 1259, 87, 1265, 87, 1260, 87, 1261, 1267, 1272, 1270, + 1271, 1262, 1273, 1275, 87, 87, 1263, 1277, 4117, 1276, + 1269, 1291, 87, 1274, 87, 1258, 87, 1259, 4117, 1278, + 87, 1260, 87, 1261, 1279, 1272, 1270, 1271, 1262, 1273, + + 1275, 87, 1280, 1263, 1277, 1281, 1276, 1282, 87, 1285, + 1284, 1288, 4117, 1286, 1290, 1293, 4117, 1289, 87, 1283, + 87, 87, 87, 1287, 1302, 1292, 87, 87, 87, 1280, + 87, 87, 1281, 1294, 1282, 87, 1285, 1284, 1288, 87, + 1286, 1290, 1293, 1295, 1289, 1296, 1283, 1297, 1300, 1303, + 1287, 87, 1292, 1304, 87, 1305, 87, 1314, 1313, 4117, + 1294, 87, 1316, 4117, 87, 87, 87, 1317, 1315, 87, + 1295, 4117, 1296, 87, 1297, 87, 1303, 87, 1318, 87, + 1304, 87, 1305, 1306, 1314, 1313, 1320, 1319, 1307, 1316, + 1308, 1322, 1321, 87, 1317, 1315, 1309, 4117, 1326, 87, + + 87, 1310, 1311, 87, 87, 1318, 87, 1333, 1312, 87, + 1306, 1325, 1323, 1320, 1319, 1307, 1324, 1308, 1322, 1321, + 87, 1328, 87, 1309, 87, 1327, 1330, 1334, 1310, 1311, + 87, 1329, 1331, 1332, 87, 1312, 87, 87, 1325, 1323, + 87, 87, 87, 1324, 1335, 1336, 1337, 87, 1328, 1338, + 87, 87, 1327, 1330, 1334, 1340, 1339, 87, 1329, 1331, + 1332, 1341, 1342, 1344, 1343, 1347, 4117, 1345, 1346, 87, + 87, 1335, 87, 1337, 1348, 4117, 1338, 87, 87, 87, + 87, 87, 1340, 1339, 87, 87, 1349, 1351, 1350, 1342, + 1344, 1343, 1352, 87, 1345, 1346, 87, 87, 1353, 87, + + 1354, 1348, 1356, 1355, 87, 1357, 1358, 1359, 1360, 87, + 87, 87, 1361, 1349, 1351, 1350, 1365, 87, 87, 1352, + 1362, 1368, 4117, 87, 87, 1353, 87, 1354, 87, 1356, + 1355, 87, 1357, 1358, 1359, 1360, 1363, 1366, 1364, 87, + 1367, 1371, 87, 1365, 87, 87, 1369, 1362, 1370, 87, + 87, 4117, 1373, 87, 87, 1374, 1375, 1372, 1376, 1379, + 1378, 87, 87, 1363, 1366, 1364, 1380, 1367, 1371, 87, + 1377, 4117, 1381, 1369, 87, 1370, 4117, 87, 87, 1373, + 87, 1382, 1374, 1375, 1372, 1376, 87, 1378, 87, 1383, + 87, 87, 1393, 87, 1384, 1385, 1390, 1377, 87, 1381, + + 1386, 1389, 1391, 87, 1387, 87, 4117, 1388, 1382, 1403, + 1392, 1394, 4117, 87, 87, 87, 1383, 87, 87, 1393, + 87, 1384, 1397, 1390, 1398, 1395, 1396, 87, 1389, 1391, + 87, 1387, 1399, 87, 1388, 1402, 1400, 1392, 1394, 87, + 1401, 87, 1405, 87, 87, 87, 1406, 87, 1404, 1397, + 1407, 1398, 1395, 1396, 87, 87, 1408, 1410, 87, 1399, + 1409, 4117, 1402, 1400, 1411, 1414, 1412, 1401, 1413, 87, + 87, 1415, 87, 1406, 87, 1404, 87, 1407, 1416, 1417, + 1424, 87, 1418, 1408, 1410, 1420, 87, 1409, 87, 87, + 87, 1411, 1414, 1412, 1419, 1413, 87, 87, 1415, 1421, + + 87, 87, 1422, 1423, 1425, 1416, 1417, 87, 87, 1418, + 1426, 4117, 1420, 1428, 1427, 87, 1429, 1434, 1432, 87, + 87, 1419, 87, 1431, 1430, 87, 1421, 1435, 4117, 1422, + 87, 1425, 87, 1433, 1436, 87, 1437, 1426, 87, 87, + 1428, 1427, 87, 1429, 1439, 1432, 1438, 87, 1440, 87, + 1431, 1430, 1441, 1443, 1444, 1442, 1445, 4117, 87, 87, + 1433, 87, 87, 1437, 1446, 1447, 87, 1448, 87, 1449, + 87, 1450, 1460, 1438, 1451, 1440, 87, 87, 1453, 1454, + 1443, 1444, 1442, 87, 87, 87, 87, 87, 87, 1452, + 1456, 1446, 87, 87, 1448, 1455, 1449, 87, 1450, 1457, + + 1458, 1451, 87, 87, 87, 1453, 1454, 1461, 87, 1462, + 1459, 87, 87, 1463, 1464, 87, 1452, 1456, 87, 1466, + 1465, 87, 1455, 1467, 1468, 1470, 1457, 1458, 87, 1473, + 1471, 87, 87, 87, 87, 87, 1462, 1459, 87, 87, + 1463, 87, 1475, 1476, 1477, 1472, 1466, 1465, 87, 4117, + 1467, 1468, 1470, 87, 1474, 1478, 1473, 1471, 1479, 1480, + 87, 1481, 87, 87, 1482, 1484, 175, 1486, 1483, 1475, + 87, 1477, 1472, 1487, 87, 1485, 87, 87, 1489, 87, + 87, 1474, 1478, 87, 1491, 1479, 1480, 87, 1481, 1488, + 1490, 1482, 1484, 87, 1486, 1483, 87, 1492, 1494, 1496, + + 87, 1493, 1485, 87, 1495, 1497, 1498, 4117, 1499, 87, + 87, 1491, 87, 1502, 1503, 1500, 1488, 4117, 87, 87, + 87, 87, 87, 1511, 1492, 1494, 1496, 87, 1493, 87, + 87, 1495, 1497, 1498, 87, 1499, 1501, 87, 1504, 1505, + 1502, 1503, 1500, 1506, 87, 1507, 1508, 87, 1510, 1509, + 87, 1522, 1512, 1513, 1514, 87, 4117, 87, 87, 4117, + 1519, 87, 1521, 1501, 87, 1504, 1505, 87, 1520, 87, + 87, 1524, 1507, 1508, 87, 1510, 1509, 1515, 87, 1512, + 1513, 1514, 1523, 87, 87, 87, 1516, 1519, 1517, 1521, + 1525, 1518, 1526, 1527, 87, 1520, 1528, 4117, 1524, 87, + + 1530, 87, 87, 87, 1515, 87, 1529, 1533, 1534, 1523, + 1532, 1538, 4117, 1516, 4117, 1517, 87, 1525, 1518, 1526, + 1527, 1531, 87, 1528, 87, 87, 1536, 1530, 1535, 87, + 87, 4117, 1537, 1529, 1539, 1534, 1540, 1532, 87, 87, + 87, 87, 87, 1541, 1542, 1543, 1544, 4117, 1531, 4117, + 87, 4117, 1547, 1536, 1560, 1535, 87, 1545, 87, 1537, + 87, 1539, 1546, 1540, 87, 1550, 87, 1548, 87, 87, + 1541, 1542, 1543, 1544, 87, 1551, 1549, 87, 1552, 1547, + 1553, 1554, 4117, 1556, 1545, 1557, 87, 87, 87, 1546, + 1555, 87, 1550, 87, 1548, 87, 4117, 87, 1558, 87, + + 4117, 1563, 1551, 1549, 87, 1552, 1561, 1553, 1554, 1559, + 1556, 1562, 1557, 87, 87, 1564, 1565, 1555, 87, 87, + 1566, 1567, 1569, 1570, 87, 1558, 1572, 87, 1563, 87, + 1568, 4117, 87, 1561, 87, 87, 1559, 1571, 1562, 1573, + 1574, 1575, 1564, 1565, 87, 1576, 1583, 1566, 1567, 1569, + 1577, 87, 87, 87, 1578, 87, 1579, 1568, 87, 87, + 87, 87, 1596, 1593, 1571, 1580, 1573, 1574, 1575, 1585, + 1581, 87, 1576, 1583, 1582, 1584, 87, 1577, 1594, 4117, + 4117, 1578, 87, 1579, 1601, 1599, 1595, 1598, 87, 87, + 1593, 1597, 87, 1605, 87, 87, 1585, 87, 4117, 87, + + 1602, 1582, 1584, 1586, 87, 1594, 1600, 1587, 87, 87, + 1588, 1589, 1599, 1595, 1598, 1590, 87, 87, 1597, 1603, + 1605, 1591, 87, 1604, 87, 1592, 1611, 1602, 1606, 87, + 1586, 4117, 1610, 1600, 1587, 87, 1607, 1588, 1589, 87, + 4117, 87, 1590, 1608, 1613, 1609, 1603, 1612, 1591, 87, + 1604, 1614, 1592, 1611, 87, 1606, 1621, 1615, 1617, 1610, + 1616, 4117, 87, 1607, 1618, 87, 1619, 87, 1620, 1622, + 1608, 1623, 1609, 4117, 1612, 1624, 87, 87, 87, 87, + 1626, 87, 1625, 87, 1615, 1617, 87, 1616, 87, 1632, + 87, 1618, 4117, 1619, 87, 1620, 1622, 87, 1634, 1633, + + 1635, 1636, 1624, 87, 1637, 87, 1639, 1626, 1643, 1625, + 1627, 87, 87, 1638, 4117, 1628, 1632, 1629, 87, 1630, + 87, 1631, 1644, 1640, 87, 1634, 1633, 1642, 87, 87, + 87, 1637, 1641, 1639, 1645, 87, 87, 1627, 1647, 1646, + 1638, 87, 1628, 1648, 1629, 87, 1630, 1651, 1631, 87, + 1640, 1649, 87, 1650, 1642, 1652, 87, 1653, 4117, 1641, + 87, 1659, 87, 1654, 1656, 1647, 87, 1655, 1661, 87, + 1648, 87, 87, 1657, 1651, 1658, 87, 1660, 1649, 87, + 1650, 87, 1652, 87, 1653, 87, 1662, 1667, 87, 1664, + 1654, 1656, 1668, 87, 1655, 1661, 1663, 1665, 1670, 1666, + + 1657, 87, 1658, 87, 1660, 87, 1669, 87, 87, 87, + 87, 87, 1671, 1662, 1667, 1672, 1664, 87, 1673, 1668, + 87, 1674, 1675, 1663, 1665, 1670, 1666, 87, 1676, 1677, + 1678, 1680, 1679, 1669, 1681, 1682, 4117, 1683, 87, 87, + 1685, 87, 1672, 87, 1684, 87, 87, 87, 1674, 1675, + 87, 87, 87, 1688, 1686, 1676, 1677, 1678, 87, 1679, + 87, 1681, 87, 87, 1683, 1689, 87, 1685, 1687, 1690, + 1691, 1684, 87, 1693, 87, 1692, 1694, 1697, 4117, 87, + 87, 1686, 87, 1695, 1696, 4117, 87, 1699, 1698, 1704, + 4117, 1701, 1689, 1700, 87, 1687, 1690, 1691, 87, 87, + + 1703, 87, 1692, 1694, 1697, 87, 1702, 87, 87, 87, + 1695, 1696, 87, 87, 1699, 1698, 1704, 1705, 1701, 87, + 1700, 1706, 87, 1708, 1707, 1709, 1710, 1703, 1714, 4117, + 1715, 4117, 4117, 1702, 1711, 87, 1712, 1716, 4117, 87, + 1713, 1718, 1722, 1717, 1705, 87, 87, 87, 1706, 87, + 1708, 1707, 1709, 1710, 87, 87, 87, 1719, 1720, 87, + 87, 1711, 87, 1712, 1716, 87, 87, 1713, 1725, 87, + 1717, 1721, 1723, 87, 1724, 87, 1727, 1726, 1731, 87, + 1728, 87, 1729, 1732, 1719, 1720, 87, 87, 1735, 87, + 87, 1733, 175, 87, 1741, 1725, 1730, 1734, 1721, 1723, + + 87, 1724, 4117, 1727, 1726, 1740, 4117, 1728, 1736, 1729, + 87, 4117, 87, 87, 1737, 87, 1738, 4117, 1733, 1743, + 87, 87, 1739, 1730, 1734, 1744, 87, 87, 1746, 87, + 1742, 1745, 1740, 1749, 87, 1736, 1752, 87, 87, 1750, + 87, 1737, 87, 1738, 1747, 1748, 1743, 87, 1754, 1739, + 1751, 87, 1744, 1757, 87, 1746, 1756, 1742, 1745, 87, + 1749, 87, 4117, 87, 1753, 1755, 1750, 87, 87, 87, + 87, 1747, 1748, 87, 1758, 1754, 1760, 1751, 1761, 1759, + 1757, 1762, 1763, 1756, 1764, 87, 1765, 87, 4117, 1771, + 1766, 1753, 1755, 1767, 1770, 1773, 1796, 87, 87, 87, + + 4117, 87, 87, 1760, 1768, 1761, 87, 1769, 1762, 1763, + 1772, 1764, 87, 1765, 87, 1775, 1771, 1766, 1774, 1776, + 1767, 1770, 1782, 87, 1779, 1777, 87, 87, 87, 87, + 1778, 1768, 87, 1783, 1769, 87, 1784, 1772, 87, 1780, + 87, 1781, 1775, 1785, 87, 1774, 1776, 1786, 4117, 1782, + 87, 1779, 87, 1787, 87, 87, 1790, 87, 87, 1789, + 1783, 1792, 1788, 1784, 1791, 87, 1780, 1793, 1781, 87, + 1785, 1795, 87, 87, 1786, 87, 1794, 1797, 4117, 87, + 1787, 4117, 1798, 1790, 1801, 87, 1789, 87, 1792, 1788, + 87, 1791, 87, 87, 1793, 1800, 87, 1799, 1795, 1803, + + 1802, 1804, 4117, 1794, 1797, 87, 1807, 87, 87, 1798, + 1805, 1801, 87, 1806, 1809, 87, 1808, 4117, 1812, 1810, + 1811, 1817, 1800, 87, 1799, 87, 1803, 1802, 1804, 87, + 87, 1814, 1818, 1807, 1816, 87, 87, 1805, 87, 1813, + 1806, 1809, 1820, 1808, 87, 1812, 1810, 1811, 1815, 87, + 1819, 87, 1821, 87, 1823, 87, 1824, 1822, 1814, 1826, + 87, 1816, 87, 87, 87, 87, 1813, 1825, 87, 1820, + 1827, 1828, 1829, 4117, 1830, 1815, 4117, 1819, 87, 87, + 1833, 1823, 1834, 1824, 1822, 4117, 1835, 1836, 1840, 87, + 1841, 87, 4117, 1831, 1825, 1832, 87, 1837, 87, 1829, + + 87, 1830, 87, 87, 87, 87, 1838, 87, 87, 1834, + 1843, 1839, 87, 1835, 1836, 1840, 87, 1841, 1842, 87, + 1831, 1844, 1832, 87, 1837, 87, 4117, 1845, 1846, 87, + 1848, 1847, 1857, 1838, 1852, 1849, 1853, 1843, 1839, 87, + 1854, 87, 1850, 87, 1855, 1842, 1858, 1851, 1856, 87, + 87, 1862, 87, 87, 1845, 1846, 87, 87, 1847, 1857, + 87, 1852, 87, 1853, 1859, 1863, 87, 1854, 87, 1860, + 1865, 1855, 87, 1858, 87, 1856, 1861, 87, 1862, 1864, + 1866, 1867, 1868, 87, 1869, 87, 1870, 1871, 87, 87, + 1873, 1859, 1872, 4117, 87, 87, 1860, 87, 1875, 1881, + + 4117, 87, 87, 1861, 1874, 87, 1864, 1866, 1867, 1868, + 1883, 1869, 87, 87, 1871, 1876, 87, 1880, 87, 1872, + 1877, 1878, 87, 87, 1879, 1875, 1881, 1882, 87, 87, + 87, 1874, 87, 1884, 1887, 1885, 87, 1883, 1886, 87, + 1888, 1889, 1876, 87, 1880, 4117, 87, 1877, 1878, 87, + 1890, 1879, 1891, 1894, 1882, 1892, 4117, 87, 1893, 1895, + 1884, 1887, 1885, 1899, 4117, 1886, 1900, 87, 87, 87, + 87, 87, 87, 87, 1896, 87, 1902, 1890, 1897, 1891, + 1894, 1908, 1892, 1901, 1903, 1893, 1895, 1904, 87, 87, + 1899, 1898, 87, 1900, 1905, 1909, 1907, 1906, 1910, 87, + + 87, 1896, 87, 1902, 87, 1897, 87, 87, 87, 87, + 1901, 1903, 1912, 1911, 1904, 1913, 1914, 87, 1898, 1915, + 1921, 1905, 1909, 1907, 1906, 87, 87, 1916, 1917, 1920, + 87, 1919, 1918, 1922, 1924, 87, 87, 1927, 87, 1912, + 1911, 87, 87, 1914, 1923, 1925, 1915, 87, 1926, 87, + 87, 87, 87, 87, 1916, 1917, 1920, 1928, 1919, 1918, + 87, 1929, 4117, 87, 1927, 1930, 87, 1931, 87, 1932, + 87, 1923, 1925, 1933, 1934, 1926, 1935, 1937, 1936, 1938, + 1939, 4117, 1941, 87, 87, 87, 87, 87, 1929, 87, + 1940, 87, 87, 1947, 1931, 1948, 87, 87, 87, 1942, + + 1933, 1934, 87, 1935, 1937, 1936, 1938, 1939, 87, 1941, + 1943, 87, 1944, 1945, 1946, 1949, 87, 1940, 1951, 1950, + 87, 87, 1948, 1954, 1959, 87, 1942, 87, 87, 1952, + 87, 87, 1957, 87, 1955, 87, 1953, 1943, 4117, 1944, + 1945, 1946, 1949, 87, 1956, 1951, 1950, 87, 1958, 87, + 1954, 87, 1965, 87, 87, 1960, 1952, 1961, 1964, 1957, + 87, 1955, 1962, 1953, 87, 1963, 87, 1966, 87, 1967, + 87, 1956, 1969, 1968, 1972, 1958, 1970, 87, 87, 1965, + 1974, 1971, 1960, 1973, 1961, 1964, 4117, 4117, 87, 1962, + 87, 4117, 1963, 1975, 1966, 87, 1967, 87, 87, 87, + + 1968, 1972, 87, 1976, 175, 1977, 1980, 1974, 87, 1981, + 1973, 87, 87, 1978, 1979, 1984, 1982, 1985, 87, 87, + 1975, 87, 1983, 1986, 87, 1990, 4117, 1988, 1987, 1991, + 1976, 1989, 1977, 1980, 87, 87, 1981, 87, 1992, 87, + 1978, 1979, 1984, 1982, 1985, 87, 1993, 87, 87, 1983, + 1986, 87, 87, 87, 1988, 1987, 1991, 1994, 1989, 1995, + 87, 1996, 1997, 1998, 2000, 1992, 4117, 2001, 4117, 87, + 1999, 2002, 2003, 1993, 2004, 4117, 2009, 87, 2006, 87, + 87, 87, 87, 2005, 1994, 2007, 1995, 2008, 2023, 1997, + 87, 2000, 87, 87, 87, 87, 87, 1999, 2002, 2003, + + 87, 2004, 87, 2009, 87, 2006, 2010, 87, 2011, 2012, + 2005, 2013, 2007, 2014, 2008, 2015, 2016, 2018, 87, 2017, + 87, 87, 4117, 87, 87, 87, 2031, 4117, 2024, 2028, + 2033, 2027, 87, 2010, 87, 2011, 2012, 87, 2013, 2022, + 2014, 87, 2015, 2016, 2018, 2019, 2017, 2025, 2020, 87, + 87, 87, 2030, 87, 87, 2024, 2028, 2029, 2027, 87, + 2021, 2032, 87, 2026, 87, 2034, 2022, 2035, 2040, 87, + 2038, 87, 2019, 2036, 2025, 2020, 87, 2037, 4117, 2030, + 4117, 2045, 87, 2039, 2029, 2042, 4117, 2021, 2032, 87, + 2026, 2043, 2041, 87, 2035, 2040, 2044, 87, 87, 87, + + 2036, 87, 87, 87, 2037, 87, 2046, 2047, 2048, 2049, + 2039, 4117, 2042, 87, 4117, 2051, 2052, 2050, 2043, 2041, + 87, 87, 2054, 2044, 2053, 2055, 2058, 2057, 2056, 4117, + 87, 87, 87, 4117, 87, 2048, 87, 87, 87, 87, + 87, 87, 2051, 87, 2050, 2060, 87, 2061, 2062, 2054, + 2059, 2053, 2055, 2058, 2057, 2056, 2063, 87, 87, 2065, + 87, 87, 2064, 2066, 87, 87, 2069, 2068, 2067, 2070, + 2072, 2071, 2060, 2073, 2061, 2062, 87, 2059, 2076, 2081, + 87, 87, 87, 2063, 87, 87, 2065, 87, 87, 2064, + 2066, 87, 2074, 2069, 2068, 2067, 2070, 2075, 2071, 2077, + + 2073, 2079, 87, 87, 87, 2076, 87, 2080, 2082, 2083, + 4117, 2085, 2089, 2088, 2084, 87, 87, 2078, 2086, 2074, + 2087, 87, 4117, 87, 2075, 87, 2077, 87, 2079, 87, + 87, 87, 2090, 87, 2080, 2082, 2083, 87, 2085, 2089, + 2088, 2084, 2091, 2093, 2078, 2086, 2095, 2087, 2094, 2096, + 87, 2097, 2100, 2092, 2101, 87, 87, 2103, 2102, 2090, + 2098, 87, 87, 2104, 87, 2099, 87, 2107, 87, 2091, + 2093, 2105, 87, 2095, 2106, 2094, 2096, 2108, 2097, 2100, + 2092, 2101, 87, 87, 87, 2102, 87, 2098, 2109, 87, + 87, 87, 2099, 2110, 2107, 2111, 2112, 2114, 2105, 2113, + + 2116, 2106, 4117, 87, 2108, 2115, 87, 87, 2117, 87, + 2120, 2127, 2126, 2118, 2119, 87, 2125, 4117, 87, 87, + 2110, 87, 2111, 2112, 2114, 87, 2113, 2116, 87, 87, + 87, 2121, 2115, 2122, 87, 2117, 2123, 2120, 87, 87, + 2118, 2119, 2124, 2125, 87, 87, 2128, 2129, 2130, 2136, + 2131, 87, 2132, 2133, 87, 2137, 2134, 4117, 2121, 87, + 2122, 2135, 87, 2123, 87, 87, 87, 2140, 2141, 2124, + 87, 87, 2143, 2128, 2129, 2130, 2136, 2131, 2139, 2132, + 2133, 2138, 2137, 87, 2146, 2142, 2148, 87, 87, 2149, + 87, 2153, 87, 87, 2140, 2141, 87, 2144, 2147, 2143, + + 4117, 2145, 2150, 2151, 87, 2139, 4117, 4117, 2138, 2152, + 87, 2146, 2142, 2148, 2154, 87, 2149, 87, 2153, 2165, + 4117, 2167, 2168, 87, 2144, 2147, 2155, 87, 2145, 2150, + 2151, 87, 2158, 2156, 2157, 87, 2152, 2159, 87, 87, + 2161, 2154, 2160, 87, 2162, 2164, 2163, 2166, 87, 87, + 2170, 87, 87, 2155, 87, 87, 87, 2169, 87, 2171, + 2156, 2157, 2172, 87, 87, 2176, 2180, 2161, 87, 2160, + 4117, 2162, 2164, 2163, 2166, 2173, 2177, 2170, 2174, 87, + 2175, 2181, 87, 87, 2169, 87, 2178, 2182, 2183, 2172, + 87, 87, 2179, 87, 2186, 87, 87, 87, 87, 2185, + + 87, 2184, 2173, 2177, 2187, 2174, 2188, 2175, 2181, 87, + 87, 2189, 2191, 2178, 2182, 2183, 87, 2192, 87, 2179, + 87, 2186, 87, 2190, 2193, 87, 2185, 2195, 2184, 87, + 87, 2187, 2196, 2188, 2197, 2198, 2199, 87, 2189, 2191, + 2200, 2203, 2204, 2201, 2192, 2194, 2202, 87, 2205, 87, + 2190, 87, 87, 4117, 87, 2206, 87, 2208, 87, 87, + 87, 2197, 2198, 87, 87, 2207, 87, 2200, 87, 2204, + 2201, 2209, 2194, 2202, 2210, 2212, 87, 2211, 2213, 4117, + 87, 87, 2206, 2218, 2208, 87, 2214, 2215, 2216, 2217, + 4117, 4117, 2207, 87, 2219, 2220, 2222, 87, 87, 2221, + + 87, 2210, 2212, 2223, 2211, 2213, 87, 87, 87, 87, + 2218, 87, 2224, 2214, 2215, 2216, 2217, 87, 175, 2225, + 87, 2219, 2220, 2222, 87, 2226, 2221, 2227, 2228, 2229, + 2223, 2230, 2231, 87, 2233, 2235, 87, 2232, 4117, 2224, + 2234, 2237, 87, 2238, 2240, 87, 87, 2236, 87, 87, + 87, 87, 2226, 87, 2227, 2228, 87, 87, 2230, 2231, + 87, 2233, 2235, 87, 2232, 2239, 2241, 2234, 2237, 2242, + 2238, 2244, 87, 2243, 2236, 2245, 87, 2246, 87, 2247, + 2249, 87, 2253, 2248, 87, 4117, 2252, 4117, 2254, 2250, + 2251, 4117, 2239, 2241, 87, 2256, 2242, 87, 87, 87, + + 2243, 87, 2245, 2255, 2246, 87, 87, 2257, 87, 4117, + 2248, 2264, 87, 2252, 87, 87, 2250, 2251, 87, 2258, + 87, 2262, 2256, 2259, 2260, 2263, 87, 2261, 87, 87, + 2255, 87, 2266, 87, 2257, 2267, 87, 4117, 2264, 2268, + 2265, 2276, 2271, 87, 87, 2269, 2258, 87, 2262, 87, + 2259, 2260, 2263, 2272, 2261, 87, 2274, 87, 2270, 2266, + 2273, 87, 2267, 87, 2275, 2277, 2268, 2265, 87, 2271, + 4117, 2278, 2269, 2279, 2280, 87, 87, 87, 87, 2282, + 2272, 2281, 87, 2274, 87, 2270, 2283, 2273, 2287, 87, + 87, 2275, 2284, 87, 2285, 2288, 2286, 87, 2278, 2289, + + 2279, 2280, 2290, 2291, 2298, 2292, 2282, 87, 2281, 87, + 2293, 2296, 2294, 2283, 87, 2287, 87, 87, 87, 2284, + 2297, 2285, 87, 2286, 2299, 2300, 87, 2295, 2302, 2290, + 87, 87, 2292, 87, 2304, 2301, 87, 2293, 87, 2294, + 2308, 2303, 2305, 87, 87, 87, 2307, 2297, 87, 2309, + 2310, 2299, 87, 2306, 2295, 87, 87, 87, 2311, 2312, + 87, 2304, 2301, 2316, 87, 2314, 2315, 87, 2303, 2305, + 87, 87, 87, 2307, 2317, 2313, 2309, 2310, 2318, 4117, + 2306, 87, 2326, 4117, 2323, 87, 2312, 87, 87, 87, + 2316, 87, 2314, 2315, 2324, 2330, 87, 2319, 2320, 2321, + + 2325, 2317, 2313, 87, 2322, 4117, 2327, 87, 2328, 2329, + 87, 2323, 87, 87, 87, 87, 2334, 87, 2331, 2333, + 2335, 2324, 2330, 2332, 2319, 2320, 2321, 2325, 87, 87, + 2337, 2322, 87, 2327, 2338, 2328, 2329, 2336, 2339, 4117, + 2344, 2340, 87, 2334, 2342, 87, 2333, 2335, 87, 2341, + 87, 2346, 87, 87, 2343, 2350, 87, 2337, 2345, 87, + 87, 2349, 87, 2347, 2336, 2339, 87, 87, 2340, 2348, + 87, 2342, 2351, 2352, 87, 2353, 2341, 87, 2346, 2355, + 87, 2343, 87, 2356, 2354, 2345, 87, 87, 2349, 2357, + 2347, 2359, 2358, 2364, 2362, 2360, 2348, 87, 87, 87, + + 2352, 87, 87, 2365, 2361, 87, 2355, 87, 2367, 87, + 87, 2354, 87, 2363, 2368, 2366, 2357, 2369, 87, 2358, + 87, 2362, 2360, 87, 2370, 2371, 87, 87, 87, 2374, + 2365, 2361, 87, 2372, 87, 2367, 2373, 2375, 2376, 2377, + 2363, 2368, 2366, 2379, 2369, 2378, 87, 87, 2382, 2380, + 87, 2370, 87, 4117, 2381, 2383, 2384, 2386, 4117, 87, + 2372, 87, 87, 2373, 2375, 87, 2377, 2385, 4117, 87, + 87, 4117, 2378, 2389, 87, 87, 2380, 2390, 87, 2387, + 87, 2381, 87, 2384, 2386, 87, 87, 2388, 2391, 2392, + 2393, 87, 87, 2394, 2385, 87, 2396, 87, 87, 2395, + + 2389, 2397, 2399, 87, 2390, 2400, 2387, 2408, 4117, 2398, + 4117, 2401, 87, 2402, 2388, 2391, 2392, 2393, 87, 87, + 2394, 4117, 87, 2396, 87, 87, 2395, 2403, 87, 2399, + 2406, 2407, 2405, 87, 87, 87, 2398, 87, 2401, 87, + 2402, 2409, 2413, 2404, 87, 2414, 2415, 2410, 2411, 2417, + 87, 2422, 4117, 87, 2403, 87, 2412, 2406, 2407, 2405, + 87, 2416, 2418, 2419, 87, 87, 2430, 87, 2409, 2413, + 2404, 87, 2414, 2415, 2410, 2411, 87, 2420, 87, 87, + 87, 2423, 2421, 2412, 2424, 2426, 87, 87, 2416, 2418, + 2419, 2425, 2435, 87, 2427, 2428, 2429, 87, 87, 87, + + 2436, 87, 87, 87, 2420, 2431, 2433, 87, 2423, 2421, + 2434, 2424, 2426, 2432, 87, 2437, 2438, 2442, 2425, 87, + 2443, 2427, 2428, 2429, 87, 87, 87, 2436, 87, 2441, + 2439, 2444, 2431, 2433, 87, 2440, 87, 2434, 87, 87, + 2432, 2447, 2437, 2438, 2442, 2445, 87, 87, 2448, 2450, + 2446, 2449, 87, 2452, 2451, 2453, 2441, 2439, 87, 2455, + 2454, 2458, 2440, 2456, 2457, 2460, 87, 2459, 2463, 87, + 87, 87, 87, 87, 87, 4117, 2450, 87, 2449, 2462, + 87, 2451, 2453, 87, 2461, 87, 2455, 2454, 2466, 87, + 2456, 2457, 2464, 87, 2459, 87, 87, 87, 2465, 2467, + + 87, 87, 2468, 4117, 2469, 87, 2462, 2471, 2470, 2472, + 175, 2461, 87, 2473, 87, 2466, 2474, 87, 2475, 2464, + 2476, 2477, 2480, 4117, 2482, 2465, 2467, 4117, 2485, 2468, + 87, 2469, 4117, 87, 87, 2470, 2472, 2478, 2481, 87, + 2473, 2479, 2483, 87, 87, 2475, 87, 87, 87, 87, + 87, 2482, 2484, 87, 87, 2485, 2486, 2488, 2491, 87, + 2489, 2487, 2492, 87, 2478, 2481, 2490, 2494, 2479, 2483, + 87, 2493, 87, 87, 87, 2495, 2497, 2496, 2498, 2484, + 2502, 87, 87, 87, 2488, 2491, 2499, 2489, 87, 2492, + 87, 2501, 2500, 2490, 2494, 2507, 87, 87, 2493, 87, + + 2510, 2505, 2495, 87, 2496, 2498, 2504, 87, 87, 2503, + 87, 2508, 2506, 2499, 87, 87, 87, 2511, 2501, 2500, + 87, 2509, 2512, 2520, 87, 4117, 87, 87, 2505, 2514, + 87, 2521, 87, 2504, 87, 2518, 2503, 2513, 2508, 2506, + 87, 2515, 87, 87, 2511, 2517, 87, 2519, 2509, 2512, + 2520, 2522, 2516, 87, 87, 2523, 2514, 87, 2521, 2525, + 2524, 2526, 2518, 2527, 2513, 87, 87, 87, 2515, 87, + 87, 2528, 2517, 2529, 2519, 87, 2534, 2532, 2522, 2516, + 2530, 87, 2523, 2531, 87, 2536, 2525, 2524, 2526, 87, + 87, 87, 2533, 2535, 87, 87, 2537, 2539, 2528, 2541, + + 2529, 2538, 2543, 87, 2532, 87, 2540, 2530, 87, 2544, + 2531, 87, 2536, 2542, 87, 87, 2546, 2547, 87, 2533, + 2535, 87, 4117, 2537, 2539, 2548, 87, 2545, 2538, 87, + 2549, 87, 87, 2540, 2550, 87, 2544, 87, 87, 87, + 2542, 2551, 2565, 2546, 2552, 2555, 87, 2553, 87, 87, + 87, 87, 2548, 2558, 2545, 2554, 4117, 2549, 2560, 87, + 2556, 2550, 2557, 2559, 2562, 87, 2561, 4117, 2551, 2565, + 87, 2552, 2555, 87, 2553, 87, 87, 87, 87, 2571, + 2558, 2563, 2554, 87, 87, 2560, 2564, 2556, 2573, 2557, + 2559, 2562, 4117, 2561, 2566, 2567, 2570, 2572, 2568, 2574, + + 2575, 4117, 2579, 87, 2576, 4117, 2571, 87, 87, 2578, + 2577, 2569, 87, 87, 4117, 87, 2582, 2581, 4117, 87, + 4117, 2566, 2567, 2570, 2572, 2568, 2574, 2575, 87, 87, + 2584, 2576, 87, 2580, 2585, 87, 2578, 2577, 2569, 87, + 87, 87, 2583, 2582, 2581, 2586, 2587, 2588, 2594, 2589, + 2590, 87, 87, 4117, 87, 87, 2592, 2584, 2591, 4117, + 2580, 2585, 2596, 87, 87, 87, 87, 2607, 87, 2583, + 2598, 2593, 2586, 2587, 2588, 87, 2589, 2590, 87, 2595, + 87, 2597, 2600, 2592, 2604, 2591, 87, 87, 2601, 2596, + 2599, 87, 2602, 87, 87, 2606, 2603, 87, 2593, 87, + + 4117, 2605, 87, 2608, 87, 2610, 2595, 2609, 2597, 2600, + 87, 2604, 2613, 87, 87, 2601, 2617, 2599, 87, 2602, + 87, 87, 2606, 2603, 2611, 87, 2616, 2614, 2605, 2612, + 2608, 87, 2610, 2615, 2609, 87, 2618, 2620, 2621, 2613, + 2622, 87, 2619, 87, 2623, 87, 87, 2625, 2624, 87, + 2626, 2628, 2629, 2616, 2614, 4117, 87, 4117, 87, 2627, + 2615, 2632, 87, 2618, 2620, 2621, 87, 2634, 87, 2619, + 2630, 2623, 87, 87, 2635, 2624, 2633, 2636, 2631, 87, + 2637, 2638, 87, 87, 87, 4117, 2627, 2639, 87, 87, + 87, 87, 2642, 87, 2634, 87, 2692, 2630, 2646, 2696, + + 87, 2635, 87, 2633, 2636, 2631, 2640, 2637, 2638, 2641, + 87, 2644, 2643, 87, 2639, 2648, 2645, 87, 87, 2642, + 2647, 2649, 2650, 2651, 87, 2646, 2653, 2657, 87, 2652, + 87, 87, 2658, 2640, 2656, 87, 2641, 87, 87, 2643, + 87, 87, 2648, 87, 4117, 87, 2654, 2647, 2649, 2650, + 2651, 87, 87, 2653, 87, 2659, 2652, 2660, 2655, 2658, + 2661, 2656, 2663, 2666, 87, 87, 87, 2662, 2664, 87, + 2665, 87, 2668, 2654, 2669, 87, 2667, 4117, 87, 87, + 87, 4117, 2659, 2670, 2660, 2655, 2671, 2661, 2675, 2663, + 2666, 87, 87, 2672, 2662, 2664, 87, 2665, 2673, 2668, + + 2681, 2669, 87, 2667, 87, 87, 2677, 2678, 2676, 87, + 2670, 2674, 87, 2671, 2680, 2675, 87, 2683, 87, 87, + 2672, 2679, 2682, 87, 2686, 2673, 4117, 87, 2684, 2688, + 2687, 2685, 87, 2677, 2678, 2676, 2697, 87, 2674, 87, + 87, 2680, 2689, 87, 87, 2693, 2690, 87, 2679, 2682, + 175, 2686, 87, 87, 87, 2684, 2688, 2687, 2685, 2691, + 2694, 2698, 2699, 2700, 2701, 2695, 2703, 87, 87, 2689, + 87, 87, 2693, 2690, 2702, 87, 2704, 2708, 87, 4117, + 2705, 87, 2709, 2714, 2710, 87, 2691, 2711, 2698, 2699, + 2700, 2701, 87, 2703, 2706, 87, 2713, 2717, 2722, 2712, + + 2715, 2702, 87, 87, 2708, 2707, 87, 2705, 87, 87, + 87, 2710, 87, 2716, 2711, 87, 2718, 87, 2719, 87, + 87, 2706, 2720, 2713, 2717, 87, 2712, 2715, 2721, 2723, + 87, 2724, 2707, 4117, 2725, 2726, 4117, 2727, 87, 87, + 2716, 2728, 87, 2718, 87, 2719, 2735, 2729, 2730, 87, + 87, 87, 87, 87, 4117, 2721, 2723, 87, 2724, 2732, + 87, 2725, 2726, 87, 2727, 2736, 2734, 2731, 2728, 2733, + 2738, 2740, 2739, 2735, 2729, 2730, 87, 87, 87, 2737, + 2741, 87, 2742, 87, 87, 2745, 2732, 87, 2743, 87, + 4117, 87, 2736, 2734, 2731, 87, 2733, 87, 2740, 2739, + + 87, 2744, 87, 2746, 2747, 2748, 2737, 2741, 2749, 2742, + 87, 87, 2745, 2750, 2751, 2743, 2752, 87, 2755, 87, + 2756, 2753, 87, 87, 87, 2761, 87, 2763, 2744, 87, + 2746, 2747, 2748, 87, 2754, 2749, 2757, 2767, 2759, 2764, + 87, 2751, 87, 2752, 87, 2755, 2758, 2756, 2753, 2760, + 2762, 87, 87, 87, 2766, 87, 2765, 87, 87, 87, + 2768, 2754, 2769, 2757, 2767, 2759, 2764, 87, 87, 87, + 87, 2770, 2771, 2758, 2773, 4117, 2760, 2762, 2772, 2774, + 2775, 2766, 87, 2765, 2777, 87, 2776, 2768, 87, 2769, + 2778, 2779, 2780, 87, 87, 4117, 2781, 2782, 87, 2771, + + 87, 2773, 87, 2786, 2792, 2772, 2774, 2775, 87, 87, + 87, 2777, 2783, 2776, 2787, 2788, 87, 87, 2779, 87, + 2789, 4117, 2784, 2781, 2782, 2785, 87, 87, 2793, 2794, + 87, 87, 2790, 2800, 2801, 2791, 2795, 2796, 2797, 2783, + 87, 2787, 2788, 2799, 87, 87, 87, 2789, 87, 2784, + 87, 87, 2785, 2798, 2803, 87, 2794, 87, 87, 2790, + 87, 87, 2791, 2795, 2796, 2797, 2802, 2804, 87, 2805, + 2799, 2806, 2808, 2807, 87, 2809, 87, 2810, 2812, 2811, + 2798, 87, 2813, 87, 2815, 87, 2819, 4117, 4117, 4117, + 87, 2814, 2818, 2802, 2804, 87, 87, 87, 2806, 87, + + 2807, 87, 87, 2816, 2810, 2812, 2811, 2817, 87, 2813, + 2821, 87, 2820, 87, 87, 87, 87, 2822, 2814, 2818, + 87, 2823, 2825, 2828, 2824, 2829, 87, 2826, 2830, 2835, + 2816, 2831, 2834, 87, 2817, 2832, 4117, 87, 4117, 2820, + 87, 4117, 2827, 87, 2822, 87, 87, 87, 2823, 2825, + 87, 2824, 2829, 87, 2826, 2830, 87, 2833, 2831, 87, + 2836, 87, 2832, 2837, 2838, 87, 2839, 87, 87, 2827, + 2841, 2840, 2842, 2845, 2843, 87, 2844, 2851, 87, 2846, + 87, 87, 2854, 87, 2833, 3787, 3788, 2836, 4117, 87, + 2837, 2838, 4117, 2839, 87, 87, 2847, 87, 2840, 2842, + + 2845, 2843, 87, 2844, 2851, 2848, 2846, 2852, 2855, 87, + 2856, 2857, 2849, 2850, 87, 87, 2858, 2859, 2863, 2860, + 87, 2853, 2864, 2847, 87, 87, 87, 2861, 87, 2862, + 87, 87, 2848, 87, 2852, 2855, 87, 2856, 2857, 2849, + 2850, 2868, 2865, 2858, 2859, 2863, 2860, 87, 2853, 2864, + 2869, 4117, 2870, 2871, 2861, 87, 2862, 2866, 2874, 2867, + 2872, 2873, 2875, 87, 4117, 87, 87, 2883, 87, 2865, + 2877, 2879, 87, 87, 87, 87, 2876, 2869, 2880, 2870, + 2871, 2884, 87, 2882, 2866, 2874, 2867, 2872, 2873, 2875, + 2878, 87, 87, 87, 87, 87, 2881, 2877, 2879, 87, + + 87, 2885, 2886, 2876, 2887, 2880, 4117, 87, 2888, 2899, + 2882, 2889, 2891, 87, 87, 2893, 2892, 2878, 87, 2890, + 4117, 87, 87, 2881, 2898, 2900, 87, 2894, 2885, 2886, + 87, 2895, 2896, 87, 2897, 2888, 87, 87, 2889, 2891, + 87, 87, 2893, 2892, 2901, 87, 2890, 2904, 2902, 87, + 87, 2898, 87, 2903, 2894, 87, 2905, 87, 2895, 2896, + 87, 2897, 2906, 4117, 2907, 87, 2912, 87, 2909, 2911, + 2916, 2901, 2908, 2910, 2904, 2902, 2918, 4117, 2917, 2913, + 2903, 87, 87, 2905, 87, 2941, 4117, 87, 2933, 87, + 87, 2907, 87, 2912, 87, 2909, 2911, 2916, 87, 2908, + + 2910, 175, 2914, 87, 2915, 2917, 2913, 2919, 2920, 87, + 2921, 2922, 2924, 2925, 2923, 87, 4117, 87, 2927, 87, + 2926, 2929, 2928, 2942, 87, 2934, 87, 87, 87, 2914, + 87, 2915, 87, 87, 2919, 2920, 87, 2921, 2922, 2924, + 2925, 2923, 2931, 87, 2930, 2927, 87, 2926, 2929, 2928, + 2932, 87, 87, 2935, 2936, 87, 2937, 2938, 4117, 4117, + 87, 87, 2939, 2940, 2944, 87, 2945, 4117, 2946, 2931, + 2943, 2930, 2947, 4117, 2948, 2952, 2951, 2932, 4117, 87, + 87, 2936, 87, 2937, 87, 87, 87, 87, 87, 2939, + 2940, 87, 2949, 2945, 87, 2946, 2950, 2943, 2953, 2947, + + 87, 2948, 87, 2951, 87, 87, 2954, 87, 2955, 2957, + 2956, 87, 4117, 4117, 2960, 2964, 2958, 2959, 4117, 2949, + 2962, 4117, 2961, 2950, 2966, 2953, 4117, 87, 87, 2963, + 2974, 87, 87, 2954, 87, 2955, 87, 2956, 87, 87, + 87, 2960, 87, 2958, 2959, 2965, 87, 2962, 2967, 2961, + 2968, 2966, 87, 2969, 2970, 87, 2963, 87, 2972, 87, + 87, 2971, 87, 2976, 2973, 87, 2975, 87, 2978, 2979, + 2977, 2980, 2965, 4117, 2981, 2967, 2984, 2968, 87, 87, + 2969, 2970, 87, 2982, 87, 2972, 87, 87, 2971, 87, + 2976, 2973, 87, 2975, 87, 2978, 2979, 2977, 2980, 2985, + + 2983, 2981, 2986, 87, 2988, 87, 87, 2989, 2987, 4117, + 2982, 2993, 3004, 87, 87, 2990, 2991, 4117, 2994, 2992, + 4117, 2995, 4117, 4117, 87, 2996, 2985, 2983, 2997, 2986, + 87, 87, 2998, 3000, 87, 2987, 87, 87, 2993, 87, + 3002, 87, 2990, 2991, 87, 2994, 2992, 87, 2995, 87, + 2999, 3003, 2996, 3005, 87, 2997, 87, 87, 3006, 2998, + 3000, 3007, 87, 3001, 87, 3008, 87, 3002, 87, 3009, + 3011, 3012, 3010, 3013, 87, 3014, 87, 2999, 3003, 87, + 3005, 87, 87, 87, 3015, 87, 3018, 87, 3007, 3020, + 3001, 3021, 3008, 3019, 3016, 87, 87, 3011, 3012, 3010, + + 3013, 3017, 3014, 87, 3022, 3023, 3025, 87, 87, 4117, + 87, 3015, 87, 3018, 3024, 87, 87, 87, 87, 3026, + 3019, 3016, 3027, 3028, 87, 4117, 3032, 3029, 3017, 4117, + 3030, 87, 3023, 3025, 3035, 3036, 87, 3031, 3034, 3037, + 87, 3024, 3039, 4117, 87, 87, 3026, 3033, 87, 3027, + 3028, 87, 87, 87, 3029, 87, 87, 3030, 87, 3038, + 3040, 3035, 3041, 3043, 3031, 3034, 3037, 87, 3042, 87, + 3044, 87, 3045, 3047, 3033, 3048, 3046, 3053, 87, 4117, + 87, 3052, 87, 87, 87, 4117, 3038, 3040, 87, 3041, + 3043, 87, 87, 3049, 3050, 3042, 3051, 3044, 87, 3045, + + 3047, 87, 3048, 3046, 87, 87, 3054, 87, 3052, 3055, + 3057, 3056, 3058, 4117, 3060, 3059, 3062, 3061, 87, 3064, + 3049, 3050, 3067, 3051, 87, 3063, 87, 87, 87, 87, + 87, 87, 3066, 3054, 87, 3069, 3055, 3057, 3056, 3058, + 87, 3060, 3059, 3062, 3061, 3068, 3064, 87, 3065, 87, + 3070, 3071, 3063, 3072, 87, 87, 3073, 87, 3074, 3066, + 3075, 3079, 87, 3076, 4117, 3077, 3080, 87, 87, 3078, + 4117, 3081, 3068, 87, 4117, 3065, 87, 87, 87, 3085, + 3072, 87, 87, 3073, 3087, 3074, 87, 3075, 3079, 87, + 3076, 87, 3077, 3080, 3082, 87, 3078, 3083, 3081, 3084, + + 3086, 87, 3088, 87, 3089, 3090, 87, 3091, 87, 3094, + 87, 87, 4117, 3092, 3098, 3093, 87, 3095, 3096, 3099, + 87, 3082, 87, 3100, 3083, 87, 3084, 3086, 3097, 87, + 87, 3089, 87, 87, 3091, 87, 3094, 87, 3103, 87, + 3092, 87, 3093, 3106, 3095, 3096, 3099, 3101, 87, 3102, + 87, 3104, 87, 3105, 87, 3097, 87, 3107, 3108, 3112, + 4117, 87, 3109, 87, 3110, 3103, 87, 3111, 4117, 3113, + 3106, 3114, 87, 3115, 3101, 3119, 3102, 87, 3104, 175, + 3105, 87, 87, 87, 3107, 3108, 3112, 87, 3118, 3109, + 3116, 3110, 3117, 87, 3111, 87, 3113, 87, 3114, 3120, + + 3115, 3121, 87, 87, 3125, 3122, 3126, 3123, 3124, 3127, + 87, 3128, 4117, 4117, 3130, 3118, 3131, 3116, 87, 3117, + 4117, 3129, 4117, 4117, 87, 87, 3120, 4117, 3121, 87, + 87, 87, 3122, 87, 3123, 3124, 3127, 87, 3128, 87, + 87, 3130, 87, 3131, 3132, 3133, 3134, 3135, 3129, 3136, + 3138, 3137, 3141, 87, 87, 87, 87, 3139, 3140, 87, + 87, 87, 3142, 3143, 87, 87, 4117, 3147, 3144, 87, + 87, 3132, 3133, 3134, 3135, 87, 3136, 3138, 3137, 3141, + 3148, 3149, 3145, 3146, 3139, 3140, 3150, 3152, 87, 3142, + 3143, 87, 87, 87, 3147, 3144, 3151, 3153, 3154, 87, + + 3155, 87, 3156, 87, 4117, 87, 3157, 3148, 87, 3145, + 3146, 87, 3158, 3150, 3152, 87, 87, 3159, 3160, 3161, + 3167, 87, 3162, 3151, 87, 3154, 3164, 87, 87, 3156, + 87, 87, 3163, 3157, 87, 3165, 3168, 87, 3166, 3158, + 87, 3169, 3171, 87, 3159, 3160, 3161, 3167, 3170, 3162, + 3172, 87, 3173, 3164, 3174, 87, 3175, 3176, 87, 3163, + 3178, 87, 3165, 87, 3177, 3166, 87, 3180, 87, 3171, + 3179, 87, 87, 87, 3181, 3170, 3182, 3172, 87, 87, + 87, 87, 3183, 3184, 3176, 3185, 3186, 3178, 87, 87, + 87, 3177, 87, 3188, 3180, 3187, 87, 3179, 3190, 3189, + + 87, 3181, 87, 87, 3191, 3192, 3193, 3194, 3195, 3183, + 3184, 87, 3185, 3186, 3198, 87, 3197, 4117, 3196, 3201, + 3188, 87, 3187, 87, 87, 3190, 3189, 3200, 3203, 87, + 87, 87, 3192, 87, 3194, 87, 87, 3199, 3209, 3208, + 3202, 3198, 4117, 3197, 87, 3196, 87, 87, 3205, 87, + 87, 3204, 3206, 3207, 3200, 3203, 87, 3210, 87, 87, + 3212, 3211, 87, 87, 3199, 87, 3208, 3202, 3215, 87, + 87, 3214, 3220, 3213, 3216, 3205, 3218, 4117, 3204, 3206, + 3207, 3217, 3219, 87, 3210, 3225, 87, 87, 3211, 87, + 3221, 87, 3222, 87, 4117, 3215, 3223, 87, 3214, 87, + + 3213, 3216, 3224, 3218, 87, 87, 87, 4117, 3217, 3219, + 87, 3228, 87, 3229, 87, 3235, 3230, 3221, 3231, 3222, + 3226, 3227, 87, 3223, 3232, 87, 3234, 3233, 4117, 3224, + 87, 87, 87, 87, 87, 3236, 3238, 3237, 3228, 3239, + 3229, 3240, 87, 3230, 3241, 3231, 87, 3226, 3227, 3242, + 87, 3232, 87, 3234, 3233, 87, 3243, 3244, 3245, 87, + 3248, 3253, 3236, 3238, 3237, 87, 3239, 3246, 87, 87, + 3247, 3241, 3250, 3249, 3251, 87, 87, 87, 87, 87, + 3260, 3252, 87, 3243, 3244, 3245, 87, 87, 87, 3254, + 3255, 3256, 87, 3257, 3246, 3258, 3259, 3247, 87, 3250, + + 3249, 3251, 3261, 87, 87, 87, 3263, 87, 3252, 87, + 3264, 87, 3262, 87, 87, 3266, 3254, 3255, 3256, 3265, + 3257, 3267, 3258, 3259, 87, 3268, 3269, 3270, 87, 3261, + 3271, 4117, 87, 87, 87, 3272, 3273, 3264, 3274, 3262, + 4117, 87, 3266, 87, 87, 87, 3265, 87, 3267, 87, + 3276, 3277, 3268, 3269, 3270, 3275, 3279, 3271, 87, 3278, + 87, 4117, 3272, 3273, 3281, 3274, 3280, 87, 87, 3282, + 3283, 3285, 87, 3284, 3287, 3286, 3290, 87, 87, 4117, + 87, 87, 3275, 3279, 87, 3288, 3278, 3289, 87, 87, + 87, 3281, 3291, 3280, 3293, 87, 175, 3283, 3285, 3292, + + 3284, 3294, 3286, 3290, 3295, 3296, 87, 87, 3297, 87, + 3298, 87, 3288, 3299, 3289, 3300, 87, 3305, 87, 3291, + 3301, 3293, 87, 87, 3303, 3302, 3292, 87, 87, 3306, + 87, 87, 3296, 3304, 4117, 3297, 3307, 3298, 4117, 87, + 87, 3311, 3300, 3308, 3305, 3309, 87, 3314, 3310, 3315, + 3312, 3303, 87, 87, 4117, 87, 3313, 3318, 3316, 87, + 3304, 87, 87, 3307, 3321, 87, 87, 87, 3311, 87, + 3308, 3317, 3309, 3319, 3320, 3310, 4117, 3312, 3326, 87, + 87, 87, 3322, 3313, 87, 3316, 87, 87, 87, 3323, + 3324, 3321, 3325, 87, 3327, 3328, 87, 87, 3317, 3330, + + 3319, 3320, 3329, 3333, 3332, 3326, 3331, 3337, 87, 3322, + 3334, 87, 87, 87, 87, 3336, 3323, 3324, 4117, 3325, + 87, 3327, 3328, 4117, 87, 87, 3330, 87, 87, 3329, + 3335, 3332, 87, 3331, 3337, 87, 3338, 3334, 3339, 87, + 3342, 3340, 3341, 3344, 87, 87, 3343, 87, 87, 3347, + 87, 87, 3348, 3345, 3346, 3351, 3349, 3335, 3358, 4117, + 4117, 3356, 3359, 3338, 87, 3339, 87, 87, 3340, 3341, + 3344, 87, 87, 3343, 87, 87, 3347, 3350, 3352, 3348, + 3345, 3346, 87, 3349, 3353, 3354, 87, 3355, 87, 87, + 87, 3357, 87, 87, 87, 3360, 87, 3361, 3362, 3363, + + 3364, 3366, 3367, 87, 3350, 3352, 87, 3365, 3369, 87, + 87, 3353, 3354, 4117, 3355, 3370, 3374, 3368, 3357, 87, + 87, 4117, 3360, 87, 3361, 3371, 87, 3364, 3366, 3367, + 87, 87, 3372, 3373, 3365, 3375, 4117, 3376, 4117, 87, + 87, 87, 3370, 87, 3368, 3377, 87, 87, 87, 3378, + 3383, 3382, 3371, 3381, 3380, 87, 3379, 3384, 3385, 3372, + 3373, 3387, 3375, 87, 3376, 87, 87, 87, 87, 87, + 3386, 87, 3377, 3388, 87, 3389, 3378, 3383, 3382, 87, + 3381, 3380, 3390, 3379, 3384, 87, 3391, 3393, 87, 3392, + 3395, 3394, 3404, 4117, 3397, 3396, 3399, 3386, 87, 3398, + + 87, 4117, 87, 3403, 4117, 87, 3405, 87, 87, 3390, + 87, 87, 87, 3391, 87, 3406, 3392, 3395, 3394, 87, + 3400, 3401, 3396, 3399, 3402, 3407, 87, 87, 87, 87, + 3403, 87, 3408, 87, 3410, 3411, 3409, 3413, 3412, 4117, + 3414, 3415, 87, 3416, 87, 87, 87, 3400, 3401, 87, + 87, 3402, 3407, 3417, 3421, 87, 3422, 3418, 3427, 3408, + 3419, 87, 3411, 3409, 87, 3412, 87, 3414, 87, 87, + 3416, 87, 3420, 3423, 3424, 3428, 3429, 3426, 3431, 3425, + 87, 3430, 87, 87, 3418, 87, 87, 3419, 3432, 3434, + 87, 3433, 3435, 3436, 3437, 87, 87, 87, 87, 3420, + + 3423, 87, 3428, 3440, 3426, 3431, 87, 3438, 87, 87, + 87, 3441, 3439, 3443, 3442, 3432, 3434, 3453, 3433, 3445, + 3446, 3447, 87, 3444, 87, 87, 87, 3448, 4117, 4117, + 87, 4117, 4117, 87, 3438, 87, 87, 3451, 87, 3439, + 3443, 3442, 87, 87, 87, 87, 3445, 3446, 3447, 3452, + 3444, 3449, 3450, 87, 3448, 3454, 3455, 3456, 87, 87, + 3457, 87, 87, 3463, 3451, 3468, 3458, 3460, 3464, 87, + 3462, 4117, 3469, 87, 3459, 4117, 3452, 3461, 3449, 3450, + 87, 3465, 3454, 3455, 87, 87, 3466, 3457, 3467, 87, + 87, 3470, 87, 3458, 3460, 87, 87, 3462, 87, 3469, + + 3471, 3459, 3472, 3474, 3461, 3473, 4117, 3477, 87, 3476, + 4117, 3475, 3480, 87, 87, 3467, 87, 87, 3470, 3478, + 3479, 3481, 4117, 3483, 3484, 87, 87, 3471, 87, 3472, + 3474, 87, 3473, 87, 3477, 3488, 3476, 87, 3475, 3480, + 87, 3482, 87, 87, 3489, 87, 3478, 3479, 3481, 87, + 3483, 3484, 3485, 3486, 3487, 4117, 3492, 3491, 3490, 87, + 87, 87, 87, 3495, 3496, 3493, 3494, 3497, 3482, 87, + 3498, 87, 87, 3499, 3500, 3503, 4117, 4117, 3501, 3485, + 3486, 3487, 87, 87, 3491, 3490, 87, 87, 87, 3502, + 3495, 87, 3493, 3494, 3497, 87, 87, 87, 3507, 3504, + + 3499, 87, 87, 3505, 3506, 3501, 3508, 87, 3512, 3509, + 3510, 3511, 4117, 87, 4117, 3513, 3502, 87, 3515, 87, + 3517, 87, 3514, 3516, 87, 87, 3504, 87, 87, 87, + 3505, 3506, 87, 87, 87, 3512, 3509, 3510, 3511, 3518, + 3519, 3520, 3513, 4117, 3522, 4117, 3521, 3517, 3524, 3514, + 87, 3526, 87, 87, 3523, 3525, 3529, 87, 3528, 3531, + 4117, 4117, 3527, 87, 3535, 4117, 3518, 3519, 3520, 87, + 87, 3522, 87, 3521, 87, 3524, 87, 87, 3526, 3530, + 87, 3523, 3525, 87, 3532, 3528, 87, 3534, 3533, 3527, + 87, 87, 87, 3536, 3537, 3538, 87, 87, 3539, 3540, + + 3544, 87, 3541, 3543, 3542, 4117, 3530, 4117, 3545, 4117, + 87, 3532, 87, 87, 3534, 3533, 3547, 3548, 4117, 3549, + 87, 3537, 87, 87, 87, 3539, 3540, 87, 3546, 3541, + 3543, 3542, 87, 3550, 87, 3545, 3551, 3552, 87, 87, + 3553, 3555, 3558, 3547, 3548, 87, 3549, 3554, 4117, 3556, + 87, 87, 3557, 3559, 87, 3546, 87, 3560, 87, 3561, + 3550, 87, 3564, 3551, 3552, 3562, 3563, 3553, 3555, 87, + 87, 3567, 87, 87, 3554, 87, 3556, 87, 3566, 3557, + 87, 3568, 3565, 4117, 87, 3569, 3561, 3571, 3570, 3564, + 87, 3573, 3562, 3563, 3575, 3572, 3574, 3577, 3579, 3578, + + 87, 87, 87, 87, 87, 3566, 87, 87, 87, 3565, + 87, 3576, 3569, 3580, 87, 3570, 87, 3581, 3573, 3582, + 87, 3575, 3572, 3574, 3583, 87, 3578, 3584, 3588, 87, + 3585, 3586, 4117, 3589, 3590, 87, 87, 4117, 3576, 87, + 3580, 87, 87, 87, 3581, 3587, 3582, 87, 87, 3591, + 87, 3583, 87, 3593, 3584, 87, 3592, 3585, 3586, 3594, + 3589, 3590, 3596, 87, 3601, 3595, 3597, 3598, 3600, 3599, + 87, 87, 3587, 87, 87, 87, 3591, 3605, 3603, 87, + 3593, 87, 3602, 3592, 87, 3606, 3594, 87, 87, 3596, + 87, 3601, 3595, 3597, 3598, 3600, 3599, 3604, 87, 3607, + + 87, 3608, 3610, 3612, 87, 3603, 3609, 87, 3613, 3602, + 3611, 3614, 87, 3615, 3616, 87, 3617, 87, 3621, 3624, + 3618, 3619, 3620, 4117, 3604, 87, 3607, 87, 3626, 3610, + 87, 87, 87, 87, 3623, 87, 3628, 3611, 3614, 3622, + 87, 3616, 87, 3617, 87, 87, 87, 3618, 3619, 3620, + 3625, 87, 87, 3630, 87, 87, 3627, 3629, 4117, 87, + 3632, 3623, 87, 3628, 87, 3631, 3622, 3634, 87, 3633, + 87, 87, 3635, 3637, 3639, 3640, 3636, 3625, 3642, 87, + 3630, 3638, 87, 3627, 3629, 87, 3641, 3632, 3646, 3643, + 87, 87, 3631, 87, 3634, 3647, 3633, 3644, 87, 3635, + + 3637, 87, 87, 3636, 3645, 87, 3648, 87, 3638, 3650, + 87, 87, 3649, 3641, 3652, 87, 3643, 3653, 87, 87, + 3654, 3655, 87, 3657, 3644, 3658, 4117, 87, 3651, 3656, + 87, 3645, 87, 3648, 3659, 87, 87, 87, 87, 3649, + 3660, 3652, 3661, 4117, 3653, 3662, 3663, 3654, 4117, 3666, + 3657, 3664, 3658, 87, 3665, 3651, 3656, 87, 3667, 3668, + 3669, 87, 87, 3670, 87, 87, 87, 3660, 3673, 87, + 87, 3671, 3662, 3663, 4117, 87, 3666, 3672, 3664, 3674, + 87, 3665, 87, 3675, 3676, 3667, 3668, 3669, 87, 3678, + 3677, 3679, 3680, 3681, 3682, 87, 4117, 87, 87, 3683, + + 87, 87, 87, 3687, 3672, 87, 3674, 3690, 3686, 3684, + 3675, 87, 87, 3685, 87, 87, 3678, 3677, 87, 3680, + 3681, 87, 87, 87, 3688, 87, 3683, 3689, 3691, 3692, + 87, 3693, 87, 3695, 3690, 3686, 3684, 3694, 87, 3696, + 3685, 3697, 3698, 3699, 3700, 3702, 87, 3701, 3705, 3703, + 4117, 3688, 4117, 87, 3689, 87, 87, 3706, 87, 87, + 3695, 87, 87, 87, 3694, 3707, 3696, 3709, 87, 87, + 87, 3700, 87, 3710, 3701, 3708, 3703, 3704, 87, 87, + 87, 3711, 3712, 3713, 3706, 3714, 87, 87, 87, 87, + 3715, 3717, 87, 87, 87, 87, 3716, 3718, 87, 3719, + + 87, 3720, 3708, 3722, 3704, 3723, 3721, 87, 3711, 3712, + 3713, 3726, 3714, 87, 87, 4117, 3727, 3715, 87, 3730, + 3724, 87, 87, 3716, 3718, 3729, 3719, 87, 3720, 3725, + 3722, 3732, 87, 3721, 3728, 3731, 87, 3733, 87, 87, + 87, 87, 87, 3727, 3734, 3736, 87, 3724, 3735, 4117, + 3740, 87, 3729, 87, 87, 87, 3725, 3737, 3732, 3738, + 3739, 3728, 3731, 3741, 3733, 3743, 87, 3742, 3744, 3746, + 3745, 3747, 3736, 4117, 4117, 3735, 87, 87, 87, 87, + 3748, 87, 3750, 4117, 3737, 87, 3738, 3739, 87, 87, + 87, 3751, 3743, 3754, 3742, 3758, 3746, 3745, 87, 3749, + + 87, 3752, 87, 3753, 3755, 87, 87, 3748, 87, 3750, + 87, 4117, 3756, 87, 3757, 87, 87, 3759, 3751, 87, + 3754, 3760, 3758, 87, 3764, 3761, 3749, 87, 3752, 87, + 3753, 3755, 87, 3762, 3763, 87, 87, 3765, 3766, 3756, + 87, 3757, 3771, 87, 3759, 3768, 3769, 87, 3760, 3767, + 3770, 3764, 3761, 3772, 3774, 87, 3773, 87, 3776, 3777, + 3762, 3763, 4117, 87, 3765, 3766, 3778, 87, 87, 3781, + 3775, 3784, 3768, 3769, 87, 87, 3767, 3770, 87, 3779, + 3772, 3774, 3780, 3773, 87, 87, 87, 3783, 3782, 87, + 3785, 87, 3786, 3778, 3791, 87, 87, 3775, 87, 3789, + + 3790, 3802, 87, 3794, 87, 3795, 3779, 3792, 3793, 3780, + 87, 3796, 3797, 3798, 3783, 3782, 3800, 3785, 3799, 87, + 3801, 87, 87, 3803, 3804, 3807, 87, 87, 87, 87, + 3794, 87, 3795, 87, 3805, 3808, 87, 3809, 3796, 87, + 3798, 3810, 3806, 87, 3811, 3799, 3813, 87, 87, 3814, + 3812, 87, 87, 87, 3817, 87, 87, 3818, 87, 3815, + 3819, 3805, 87, 87, 3809, 3816, 87, 87, 3810, 3806, + 3820, 3811, 87, 87, 87, 3822, 3814, 3812, 87, 3821, + 87, 3817, 87, 3823, 3818, 3824, 3815, 3819, 87, 3825, + 4117, 3826, 3816, 3827, 3828, 3829, 3830, 3820, 4117, 3831, + + 87, 87, 3822, 3832, 3835, 87, 3821, 87, 3837, 3836, + 3823, 87, 87, 4117, 4117, 3845, 3825, 87, 3826, 3841, + 87, 87, 87, 3830, 3833, 87, 3831, 3834, 3840, 3838, + 3832, 87, 3839, 3844, 87, 3842, 87, 3843, 3847, 3848, + 87, 87, 87, 3851, 87, 87, 3841, 87, 3846, 3849, + 3850, 3833, 3853, 3854, 3834, 3840, 3838, 87, 3852, 3839, + 87, 87, 3842, 3855, 3843, 87, 87, 3857, 3858, 87, + 87, 87, 87, 3856, 3859, 3846, 3849, 3850, 3860, 87, + 87, 87, 87, 3861, 3862, 3852, 3863, 3864, 3865, 87, + 3855, 3866, 3867, 3870, 87, 87, 3868, 3869, 3874, 4117, + + 3856, 87, 4117, 87, 87, 87, 4117, 3872, 3875, 87, + 87, 87, 3876, 87, 87, 3865, 87, 3871, 3866, 87, + 3870, 3873, 3879, 3868, 3869, 87, 87, 87, 3878, 87, + 3877, 3881, 3884, 87, 3872, 3875, 3883, 87, 3880, 3876, + 87, 3882, 4117, 3885, 3871, 3886, 87, 87, 3873, 87, + 87, 3887, 3888, 87, 3889, 3878, 4117, 3877, 87, 3884, + 87, 3890, 3891, 3883, 87, 3880, 3892, 3895, 3882, 87, + 3885, 87, 3886, 3893, 87, 3894, 87, 3897, 87, 3888, + 3896, 87, 4117, 87, 3898, 3903, 3899, 3900, 3890, 3891, + 87, 3907, 3902, 3892, 3895, 87, 3901, 87, 3904, 3905, + + 3893, 87, 3894, 87, 87, 87, 87, 3896, 87, 87, + 3910, 3898, 3903, 3899, 3900, 3906, 87, 87, 3907, 3902, + 3908, 87, 87, 3901, 3909, 3904, 3905, 87, 3911, 3914, + 3912, 87, 87, 3915, 3918, 3913, 3919, 3910, 3916, 3917, + 3920, 87, 3906, 87, 3921, 3922, 87, 3908, 87, 3923, + 87, 3909, 87, 87, 87, 3911, 3914, 3912, 3926, 3925, + 3915, 3918, 3913, 3919, 3924, 3916, 3917, 87, 87, 3936, + 3928, 87, 87, 3927, 3929, 3930, 87, 87, 3932, 3931, + 87, 87, 87, 87, 3934, 3926, 3925, 87, 3933, 3937, + 3935, 3924, 4117, 4117, 87, 87, 3936, 3928, 4117, 3939, + + 3927, 3929, 87, 87, 3938, 3932, 3931, 87, 87, 87, + 87, 3934, 87, 3940, 3943, 3933, 3937, 3935, 3941, 3944, + 87, 3942, 3945, 3946, 87, 3948, 3939, 3947, 3949, 87, + 3950, 3938, 87, 87, 87, 3954, 87, 4117, 3962, 3952, + 3940, 3943, 87, 4117, 87, 3941, 3944, 87, 3942, 3945, + 3946, 3951, 3948, 87, 3947, 3949, 3953, 87, 87, 3959, + 3955, 3956, 87, 3957, 3958, 87, 3952, 87, 3961, 87, + 87, 87, 3960, 3964, 3963, 87, 3965, 3968, 3951, 3967, + 3966, 87, 87, 3953, 3969, 87, 3959, 3955, 3956, 4117, + 3957, 3958, 87, 3973, 3972, 3961, 3975, 87, 87, 3960, + + 3964, 3963, 87, 87, 87, 87, 3967, 3966, 3970, 3974, + 3971, 87, 3976, 3977, 3978, 87, 87, 87, 87, 3979, + 3973, 3972, 3980, 3975, 87, 3981, 3982, 87, 3983, 3984, + 3985, 87, 3986, 87, 87, 3970, 3974, 3971, 3987, 3976, + 3988, 3978, 3989, 3990, 87, 87, 3979, 87, 3991, 3980, + 3992, 3993, 87, 3982, 3995, 87, 87, 87, 3994, 87, + 87, 3996, 87, 87, 3997, 3987, 87, 3988, 3998, 87, + 3990, 87, 4000, 87, 3999, 87, 4001, 87, 3993, 4002, + 87, 87, 4003, 87, 4004, 3994, 4005, 4006, 3996, 4117, + 87, 3997, 4117, 4007, 4010, 3998, 4008, 4009, 87, 87, + + 87, 3999, 87, 4001, 87, 4011, 4002, 87, 4018, 4003, + 4012, 4015, 4117, 4013, 4006, 4014, 87, 87, 87, 87, + 4007, 87, 87, 4008, 4009, 87, 4016, 87, 4017, 4020, + 4117, 4023, 87, 87, 4019, 87, 4021, 4012, 4015, 87, + 4013, 87, 4014, 87, 4022, 87, 4024, 4027, 4025, 4026, + 4028, 4029, 87, 4016, 4117, 4017, 4020, 87, 4023, 4030, + 87, 4019, 87, 4021, 4031, 87, 87, 4036, 4037, 87, + 87, 4022, 87, 4024, 4027, 4025, 4026, 4028, 87, 4032, + 4033, 4034, 4038, 4039, 4035, 87, 4030, 87, 87, 4044, + 87, 4031, 87, 4040, 4036, 87, 4041, 87, 4045, 4042, + + 4043, 4048, 4049, 4117, 87, 4046, 4032, 4033, 4034, 4038, + 4047, 4035, 87, 4050, 4051, 87, 4044, 87, 87, 87, + 4040, 87, 87, 4041, 87, 4052, 4042, 4043, 4048, 87, + 87, 4053, 4046, 4055, 87, 87, 4054, 4047, 4056, 4057, + 4050, 87, 4058, 4059, 87, 4060, 87, 87, 4061, 4062, + 4063, 87, 4052, 87, 87, 4064, 4065, 4066, 4053, 87, + 4055, 4067, 4117, 4054, 4068, 4056, 4057, 4069, 4117, 4076, + 4059, 4073, 4060, 4117, 87, 87, 87, 87, 87, 87, + 4074, 87, 4064, 4065, 87, 4070, 4072, 4071, 4067, 87, + 4075, 4068, 87, 87, 4069, 87, 4076, 87, 4073, 4078, + + 87, 4079, 87, 4080, 87, 4077, 87, 4074, 4081, 87, + 4084, 4082, 4070, 4072, 4071, 4085, 4083, 4075, 87, 4086, + 4088, 4089, 4087, 4095, 4117, 87, 4078, 4117, 4079, 87, + 4080, 4090, 4077, 87, 87, 4081, 87, 4084, 4082, 4091, + 4093, 4117, 87, 4083, 87, 87, 87, 4088, 87, 4087, + 87, 87, 4092, 4094, 4097, 4096, 4098, 4099, 4090, 87, + 87, 87, 87, 87, 4100, 87, 4091, 4093, 4101, 4102, + 4117, 4106, 87, 4105, 4108, 4109, 87, 4103, 87, 4092, + 4094, 4097, 4096, 4098, 4099, 87, 4107, 4110, 4111, 4104, + 4112, 4100, 4115, 4116, 87, 4101, 87, 87, 87, 87, + + 4105, 87, 87, 4113, 4103, 4117, 87, 87, 4117, 4117, + 87, 87, 87, 4107, 4110, 4111, 4104, 4112, 4114, 87, + 87, 4117, 4117, 4117, 4117, 4117, 87, 4117, 4117, 4117, + 4113, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, + 4117, 4117, 4117, 4117, 4117, 4114, 48, 48, 48, 48, + 48, 48, 48, 53, 53, 53, 53, 53, 53, 53, + 58, 58, 58, 58, 58, 58, 58, 64, 64, 64, + 64, 64, 64, 64, 69, 69, 69, 69, 69, 69, + 69, 75, 75, 75, 75, 75, 75, 75, 81, 81, + 81, 81, 81, 81, 81, 90, 90, 4117, 90, 90, + + 90, 90, 165, 165, 4117, 4117, 4117, 165, 165, 167, + 167, 4117, 4117, 167, 4117, 167, 169, 4117, 4117, 4117, + 4117, 4117, 169, 172, 172, 4117, 4117, 4117, 172, 172, + 174, 4117, 4117, 4117, 4117, 4117, 174, 176, 176, 4117, + 176, 176, 176, 176, 179, 4117, 4117, 4117, 4117, 4117, + 179, 182, 182, 4117, 4117, 4117, 182, 182, 91, 91, + 4117, 91, 91, 91, 91, 17, 4117, 4117, 4117, 4117, + 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, + 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, + 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, + + 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, + 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, + 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, + 4117, 4117 } ; -static const flex_int16_t yy_chk[11526] = +static const flex_int16_t yy_chk[11833] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -3033,16 +3100,16 @@ static const flex_int16_t yy_chk[11526] = 7, 7, 7, 33, 7, 8, 8, 8, 8, 32, 8, 9, 9, 9, 10, 10, 10, 19, 52, 52, - 4023, 19, 238, 3, 32, 33, 4, 68, 68, 5, - 33, 6, 3247, 13, 13, 13, 13, 7, 13, 14, + 4125, 19, 238, 3, 32, 33, 4, 68, 68, 5, + 33, 6, 3282, 13, 13, 13, 13, 7, 13, 14, 14, 14, 14, 8, 14, 15, 15, 15, 9, 25, 238, 10, 11, 11, 11, 11, 11, 11, 12, 12, 12, 12, 12, 12, 16, 16, 16, 34, 28, 85, - 85, 13, 11, 46, 1235, 25, 25, 14, 12, 34, - 310, 23, 15, 23, 23, 46, 23, 1222, 28, 88, + 85, 13, 11, 46, 1242, 25, 25, 14, 12, 34, + 311, 23, 15, 23, 23, 46, 23, 1229, 28, 88, 11, 28, 23, 88, 34, 28, 12, 166, 166, 11, - 46, 16, 173, 173, 57, 12, 30, 57, 29, 310, - 45, 182, 37, 73, 30, 28, 26, 1222, 37, 23, + 46, 16, 173, 173, 57, 12, 30, 57, 29, 311, + 45, 182, 37, 73, 30, 28, 26, 1229, 37, 23, 24, 24, 29, 26, 24, 30, 73, 26, 181, 24, 26, 24, 30, 30, 29, 29, 45, 45, 24, 37, @@ -3068,18 +3135,18 @@ static const flex_int16_t yy_chk[11526] = 71, 155, 107, 76, 40, 40, 80, 40, 80, 80, 107, 80, 100, 117, 113, 106, 40, 40, 117, 75, - 188, 40, 1053, 113, 188, 87, 202, 87, 87, 107, + 188, 40, 1059, 113, 188, 87, 202, 87, 87, 107, 87, 40, 40, 71, 40, 41, 87, 90, 41, 90, 90, 113, 90, 103, 103, 41, 104, 188, 90, 41, - 41, 108, 104, 1053, 104, 114, 103, 41, 202, 105, + 41, 108, 104, 1059, 104, 114, 103, 41, 202, 105, 105, 69, 41, 64, 114, 41, 122, 104, 105, 108, 103, 103, 41, 104, 122, 90, 41, 41, 118, 104, 110, 104, 114, 108, 112, 112, 105, 105, 116, 110, - 120, 118, 112, 122, 59, 116, 108, 127, 360, 121, + 120, 118, 112, 122, 59, 116, 108, 127, 361, 121, 112, 119, 110, 58, 119, 118, 228, 110, 53, 124, 123, 112, 112, 124, 120, 116, 110, 119, 119, 112, - 127, 121, 120, 130, 127, 119, 121, 360, 119, 124, + 127, 121, 120, 130, 127, 119, 121, 361, 119, 124, 123, 119, 123, 124, 125, 126, 124, 123, 228, 125, 124, 120, 125, 130, 119, 119, 129, 131, 126, 132, 130, 133, 134, 129, 136, 135, 124, 123, 133, 137, @@ -3105,14 +3172,14 @@ static const flex_int16_t yy_chk[11526] = 192, 195, 194, 189, 196, 190, 186, 193, 185, 197, 191, 0, 200, 176, 187, 189, 190, 185, 191, 192, 196, 195, 193, 189, 194, 205, 198, 197, 206, 194, - 189, 196, 198, 199, 200, 199, 197, 0, 201, 200, + 189, 196, 198, 199, 200, 199, 197, 203, 201, 200, 201, 203, 207, 206, 209, 203, 208, 207, 210, 212, - 213, 205, 205, 211, 208, 206, 212, 822, 198, 198, - 199, 214, 203, 620, 201, 201, 209, 201, 211, 203, + 213, 205, 205, 211, 208, 206, 212, 826, 198, 198, + 199, 214, 203, 623, 201, 201, 209, 201, 211, 203, 210, 209, 203, 208, 207, 210, 212, 215, 213, 0, - 211, 216, 213, 217, 214, 218, 822, 239, 214, 203, - 204, 620, 216, 220, 221, 204, 217, 218, 0, 215, + 211, 216, 213, 217, 214, 218, 826, 239, 214, 203, + 204, 623, 216, 220, 221, 204, 217, 218, 0, 215, 204, 222, 220, 224, 215, 213, 204, 204, 216, 225, 217, 219, 218, 204, 219, 0, 221, 204, 225, 239, 220, 221, 204, 222, 226, 224, 219, 204, 222, 227, @@ -3141,1155 +3208,1189 @@ static const flex_int16_t yy_chk[11526] = 289, 282, 290, 284, 286, 293, 288, 295, 297, 296, 300, 0, 298, 287, 288, 299, 305, 301, 292, 300, 289, 0, 291, 292, 298, 302, 303, 306, 299, 295, - 294, 296, 307, 322, 295, 301, 296, 300, 302, 298, - - 297, 304, 299, 304, 301, 303, 308, 311, 305, 309, - 314, 306, 302, 303, 306, 312, 311, 307, 313, 307, - 317, 314, 316, 324, 315, 322, 323, 326, 304, 325, - 318, 0, 308, 308, 311, 309, 309, 314, 315, 323, - 319, 312, 312, 317, 313, 313, 316, 317, 318, 316, - 315, 315, 320, 323, 325, 324, 325, 318, 319, 326, - 320, 327, 330, 328, 329, 315, 332, 319, 331, 334, - 0, 333, 0, 332, 0, 334, 336, 337, 327, 320, - 333, 335, 0, 0, 327, 342, 329, 339, 327, 328, - 328, 329, 331, 332, 330, 335, 334, 338, 333, 340, - - 331, 337, 336, 336, 337, 327, 338, 340, 335, 341, - 339, 342, 342, 343, 339, 344, 345, 347, 341, 331, - 346, 0, 343, 349, 338, 351, 340, 348, 352, 359, - 356, 353, 344, 0, 359, 346, 341, 352, 349, 344, - 343, 0, 344, 351, 356, 355, 376, 346, 345, 347, - 349, 348, 351, 353, 348, 352, 0, 356, 353, 344, - 350, 359, 357, 358, 358, 350, 362, 0, 350, 355, - 361, 0, 355, 350, 350, 350, 350, 357, 376, 0, - 0, 0, 0, 350, 364, 369, 365, 350, 358, 357, - 358, 358, 350, 362, 361, 350, 364, 361, 365, 370, - - 350, 350, 350, 350, 354, 367, 354, 363, 354, 368, - 363, 364, 369, 365, 366, 366, 0, 363, 354, 354, - 354, 370, 354, 367, 366, 371, 370, 368, 354, 372, - 0, 354, 367, 354, 363, 354, 368, 363, 373, 375, - 373, 366, 366, 377, 381, 354, 354, 354, 374, 354, - 379, 371, 371, 0, 378, 372, 372, 379, 377, 380, - 374, 375, 378, 0, 0, 373, 375, 382, 385, 382, - 377, 380, 384, 0, 386, 374, 381, 379, 382, 384, - 387, 378, 388, 0, 0, 382, 380, 389, 388, 389, - 385, 391, 396, 382, 382, 385, 382, 390, 395, 384, - - 393, 0, 387, 0, 388, 382, 386, 387, 394, 388, - 390, 389, 382, 392, 389, 388, 389, 397, 393, 396, - 402, 400, 0, 391, 390, 401, 392, 393, 400, 392, - 395, 392, 402, 403, 394, 394, 414, 392, 404, 397, - 392, 407, 414, 401, 397, 403, 410, 402, 400, 401, - 406, 404, 401, 392, 407, 412, 392, 409, 392, 398, - 403, 398, 0, 414, 410, 404, 406, 398, 407, 409, - 401, 398, 415, 410, 406, 422, 398, 406, 411, 398, - 415, 419, 422, 411, 409, 398, 398, 412, 398, 416, - 413, 475, 418, 406, 398, 0, 417, 413, 398, 415, - - 418, 416, 422, 398, 421, 421, 398, 399, 425, 399, - 411, 413, 420, 419, 417, 423, 416, 413, 475, 418, - 428, 420, 399, 417, 413, 399, 425, 399, 423, 399, - 425, 421, 428, 399, 399, 425, 399, 426, 427, 420, - 432, 424, 423, 0, 426, 427, 0, 428, 431, 399, - 424, 435, 399, 425, 399, 0, 399, 408, 408, 429, - 431, 430, 0, 433, 426, 427, 435, 408, 408, 408, - 408, 408, 432, 424, 408, 431, 438, 424, 435, 437, - 434, 429, 408, 430, 408, 408, 429, 434, 430, 433, - 433, 436, 437, 441, 408, 408, 408, 408, 408, 440, - - 436, 408, 439, 0, 439, 449, 437, 434, 438, 443, - 440, 442, 442, 0, 444, 441, 443, 445, 436, 446, - 441, 444, 447, 448, 0, 458, 440, 449, 445, 439, - 446, 0, 449, 450, 450, 447, 443, 453, 458, 451, - 442, 444, 452, 455, 445, 454, 446, 461, 448, 447, - 448, 450, 458, 454, 463, 455, 456, 452, 450, 457, - 450, 450, 451, 453, 453, 452, 451, 456, 457, 452, - 455, 462, 454, 459, 459, 465, 463, 466, 450, 461, - 464, 463, 0, 456, 452, 459, 457, 459, 0, 462, - 467, 0, 459, 465, 470, 468, 467, 0, 462, 473, - - 459, 459, 465, 464, 0, 474, 469, 464, 471, 466, - 0, 480, 459, 472, 459, 460, 468, 467, 470, 474, - 472, 470, 468, 460, 460, 473, 473, 460, 460, 469, - 471, 460, 474, 469, 477, 471, 476, 460, 478, 482, - 472, 479, 460, 480, 476, 483, 0, 481, 485, 486, - 460, 460, 478, 484, 460, 460, 477, 483, 460, 484, - 505, 477, 482, 476, 488, 478, 482, 479, 479, 481, - 485, 486, 483, 487, 481, 485, 486, 489, 490, 488, - 484, 487, 491, 492, 489, 0, 493, 490, 494, 495, - 496, 488, 505, 499, 494, 497, 0, 491, 0, 487, - - 487, 493, 500, 0, 489, 490, 498, 492, 487, 491, - 492, 495, 496, 493, 502, 494, 495, 496, 497, 499, - 499, 498, 497, 503, 500, 501, 0, 506, 503, 500, - 508, 501, 509, 498, 515, 514, 508, 510, 511, 512, - 502, 502, 514, 510, 520, 512, 513, 522, 519, 515, - 503, 509, 501, 506, 506, 519, 511, 508, 517, 509, - 517, 515, 514, 518, 510, 511, 512, 517, 513, 521, - 525, 524, 518, 513, 596, 519, 520, 523, 526, 522, - 523, 527, 521, 596, 533, 517, 529, 517, 523, 524, - 518, 531, 528, 530, 527, 528, 521, 532, 524, 535, - - 526, 596, 525, 531, 523, 526, 530, 523, 527, 538, - 529, 528, 536, 529, 534, 532, 533, 0, 531, 528, - 530, 534, 528, 535, 532, 537, 535, 539, 540, 542, - 541, 538, 539, 544, 540, 536, 538, 543, 537, 542, - 546, 534, 547, 545, 536, 544, 553, 548, 0, 554, - 547, 546, 537, 541, 539, 540, 542, 541, 553, 543, - 544, 548, 536, 0, 543, 545, 0, 546, 0, 547, - 545, 551, 554, 553, 548, 549, 554, 552, 551, 555, - 549, 556, 549, 552, 557, 0, 0, 555, 549, 558, - 549, 0, 559, 549, 549, 557, 559, 0, 551, 0, - - 549, 549, 549, 556, 552, 0, 555, 549, 556, 549, - 560, 557, 558, 561, 559, 549, 558, 549, 565, 559, - 549, 549, 560, 559, 563, 562, 567, 549, 562, 564, - 565, 569, 566, 561, 0, 561, 562, 560, 569, 564, - 561, 570, 563, 566, 568, 565, 572, 571, 568, 571, - 567, 563, 562, 567, 576, 562, 577, 573, 569, 566, - 561, 564, 574, 575, 577, 578, 564, 570, 570, 573, - 578, 568, 572, 572, 571, 575, 579, 574, 580, 581, - 576, 576, 582, 577, 573, 585, 583, 581, 0, 574, - 575, 587, 578, 586, 582, 589, 580, 593, 579, 588, - - 585, 590, 594, 579, 0, 580, 581, 583, 603, 582, - 593, 586, 585, 583, 587, 592, 590, 591, 587, 595, - 586, 0, 588, 592, 593, 597, 588, 589, 590, 591, - 599, 595, 600, 598, 594, 600, 602, 601, 604, 605, - 603, 606, 592, 607, 591, 608, 595, 598, 597, 609, - 618, 612, 597, 604, 610, 599, 601, 599, 607, 600, - 598, 611, 609, 602, 601, 604, 610, 613, 615, 608, - 607, 605, 608, 606, 612, 614, 609, 618, 612, 615, - 619, 610, 614, 611, 616, 614, 617, 621, 611, 616, - 622, 613, 624, 614, 613, 615, 623, 0, 625, 626, - - 617, 629, 614, 625, 627, 628, 0, 619, 626, 614, - 627, 630, 614, 617, 631, 632, 616, 622, 638, 621, - 628, 633, 631, 623, 624, 629, 626, 634, 629, 636, - 625, 627, 628, 630, 632, 635, 637, 636, 630, 635, - 639, 631, 632, 640, 641, 633, 642, 639, 633, 634, - 638, 643, 646, 641, 634, 644, 636, 645, 646, 637, - 0, 647, 635, 637, 643, 649, 640, 639, 642, 645, - 640, 641, 648, 642, 651, 652, 649, 653, 643, 646, - 648, 644, 644, 647, 645, 655, 650, 657, 647, 656, - 653, 0, 649, 650, 655, 659, 657, 652, 660, 648, - - 654, 665, 652, 0, 653, 654, 651, 658, 654, 654, - 661, 666, 655, 650, 657, 656, 656, 659, 658, 662, - 660, 664, 659, 661, 654, 660, 667, 654, 0, 666, - 670, 662, 654, 665, 658, 654, 654, 661, 666, 668, - 671, 669, 674, 672, 673, 664, 662, 0, 664, 669, - 667, 674, 670, 667, 675, 673, 677, 670, 676, 679, - 683, 668, 668, 0, 671, 672, 668, 671, 669, 674, - 672, 673, 676, 678, 675, 680, 681, 682, 677, 685, - 678, 675, 683, 677, 681, 676, 679, 683, 668, 682, - 684, 687, 685, 680, 686, 688, 684, 689, 690, 691, - - 678, 693, 680, 681, 682, 686, 685, 692, 692, 687, - 688, 694, 693, 701, 697, 695, 703, 684, 687, 690, - 704, 686, 688, 691, 696, 690, 691, 697, 693, 689, - 698, 699, 700, 696, 702, 694, 692, 695, 694, 714, - 700, 697, 695, 698, 704, 701, 706, 704, 703, 707, - 705, 696, 705, 699, 710, 709, 702, 698, 699, 700, - 707, 702, 708, 717, 712, 711, 710, 708, 706, 709, - 0, 714, 715, 706, 719, 716, 707, 705, 712, 718, - 715, 710, 709, 711, 723, 717, 718, 720, 721, 0, - 717, 712, 711, 716, 708, 713, 0, 713, 724, 715, - - 719, 719, 716, 722, 713, 0, 718, 720, 721, 727, - 725, 713, 713, 724, 720, 721, 723, 796, 722, 713, - 725, 726, 713, 729, 713, 724, 726, 722, 732, 731, - 722, 713, 725, 730, 732, 727, 727, 725, 713, 713, - 728, 730, 728, 733, 796, 722, 739, 725, 729, 734, - 729, 736, 733, 726, 731, 732, 731, 735, 734, 736, - 730, 737, 738, 740, 744, 741, 735, 728, 737, 739, - 733, 742, 744, 739, 747, 746, 734, 741, 736, 0, - 743, 740, 0, 742, 735, 786, 745, 746, 737, 743, - 740, 744, 741, 748, 738, 745, 749, 750, 742, 752, - - 748, 0, 746, 751, 754, 752, 747, 743, 753, 749, - 745, 751, 750, 745, 756, 0, 753, 786, 0, 755, - 748, 761, 745, 749, 750, 756, 752, 754, 755, 757, - 751, 754, 759, 758, 758, 753, 760, 762, 757, 763, - 759, 756, 758, 761, 760, 764, 755, 766, 761, 765, - 762, 767, 0, 769, 0, 766, 757, 768, 770, 759, - 758, 758, 765, 760, 762, 763, 763, 767, 764, 770, - 768, 771, 764, 772, 766, 769, 765, 773, 767, 771, - 769, 774, 775, 776, 768, 770, 776, 772, 781, 777, - 778, 0, 779, 780, 782, 0, 783, 773, 771, 803, - - 772, 779, 775, 774, 773, 787, 781, 782, 774, 775, - 776, 777, 778, 780, 783, 781, 777, 778, 784, 779, - 780, 782, 785, 783, 788, 0, 790, 787, 791, 789, - 792, 803, 787, 0, 793, 802, 784, 785, 795, 790, - 0, 794, 792, 802, 795, 784, 791, 806, 788, 785, - 799, 788, 789, 790, 794, 791, 789, 792, 793, 797, - 800, 793, 802, 804, 798, 795, 805, 797, 794, 798, - 806, 804, 799, 805, 806, 809, 807, 799, 800, 808, - 810, 808, 811, 814, 809, 797, 797, 800, 812, 813, - 804, 807, 814, 805, 797, 815, 798, 815, 816, 0, - - 827, 819, 809, 807, 0, 816, 808, 812, 823, 813, - 814, 0, 810, 819, 811, 812, 813, 0, 823, 0, - 826, 827, 815, 831, 0, 816, 817, 827, 819, 817, - 0, 830, 829, 817, 832, 823, 817, 829, 826, 833, - 0, 831, 834, 817, 817, 832, 817, 826, 835, 836, - 831, 817, 830, 817, 838, 837, 817, 840, 830, 829, - 817, 832, 833, 817, 837, 836, 833, 838, 834, 834, - 817, 817, 839, 817, 835, 835, 836, 842, 845, 839, - 843, 838, 837, 0, 842, 844, 846, 845, 849, 840, - 0, 844, 847, 0, 0, 847, 0, 0, 848, 839, - - 841, 841, 843, 841, 842, 845, 841, 843, 850, 846, - 849, 841, 844, 846, 848, 849, 850, 841, 841, 847, - 841, 848, 852, 856, 851, 848, 841, 841, 841, 853, - 841, 853, 855, 841, 852, 850, 854, 855, 841, 857, - 858, 848, 860, 856, 841, 841, 851, 841, 859, 852, - 856, 851, 858, 862, 861, 864, 853, 863, 865, 866, - 854, 0, 0, 854, 855, 857, 857, 858, 860, 860, - 859, 868, 0, 872, 866, 859, 861, 862, 873, 863, - 862, 861, 864, 865, 863, 865, 866, 867, 869, 870, - 874, 871, 872, 876, 868, 867, 870, 869, 868, 871, - - 872, 875, 874, 877, 873, 873, 876, 879, 875, 881, - 878, 882, 883, 886, 867, 869, 870, 874, 871, 878, - 876, 880, 879, 887, 888, 892, 880, 884, 875, 877, - 877, 896, 884, 882, 879, 886, 889, 878, 882, 883, - 886, 881, 890, 893, 894, 889, 891, 895, 880, 888, - 890, 888, 896, 891, 898, 887, 897, 892, 896, 884, - 899, 901, 903, 889, 0, 893, 905, 904, 900, 890, - 893, 895, 909, 891, 895, 897, 894, 900, 913, 912, - 901, 898, 902, 897, 903, 907, 905, 899, 901, 903, - 904, 902, 906, 905, 904, 900, 907, 908, 910, 909, - - 915, 906, 911, 0, 914, 908, 912, 957, 915, 902, - 913, 918, 907, 914, 917, 920, 910, 919, 919, 906, - 918, 911, 921, 922, 908, 910, 922, 915, 923, 911, - 924, 914, 917, 920, 921, 925, 926, 927, 918, 957, - 923, 917, 920, 928, 919, 929, 0, 929, 930, 921, - 922, 931, 924, 925, 933, 923, 928, 924, 934, 927, - 926, 936, 925, 926, 927, 931, 930, 933, 932, 936, - 928, 935, 929, 932, 937, 930, 938, 939, 931, 938, - 942, 933, 940, 935, 934, 934, 939, 943, 936, 944, - 940, 945, 937, 946, 0, 944, 0, 947, 935, 946, - - 932, 937, 0, 938, 939, 942, 940, 942, 948, 940, - 954, 952, 0, 945, 943, 948, 944, 940, 945, 947, - 946, 949, 950, 951, 947, 955, 958, 950, 949, 952, - 951, 956, 953, 954, 955, 948, 953, 954, 952, 956, - 959, 963, 964, 960, 958, 967, 0, 962, 949, 950, - 951, 966, 955, 958, 960, 959, 961, 968, 956, 953, - 962, 964, 963, 965, 961, 968, 972, 959, 963, 964, - 960, 970, 967, 966, 962, 969, 965, 978, 966, 971, - 973, 976, 969, 961, 968, 972, 971, 973, 976, 970, - 965, 974, 975, 972, 977, 979, 974, 980, 970, 981, - - 975, 977, 969, 982, 984, 983, 971, 973, 976, 978, - 980, 985, 983, 992, 986, 987, 982, 989, 974, 975, - 988, 977, 991, 987, 980, 993, 994, 979, 988, 995, - 982, 981, 983, 997, 990, 988, 984, 986, 995, 989, - 990, 986, 987, 985, 989, 992, 996, 988, 991, 991, - 994, 998, 999, 994, 1000, 988, 995, 993, 998, 0, - 996, 990, 1001, 1000, 1002, 997, 1004, 1006, 1005, 1003, - 1008, 1004, 0, 996, 1007, 1008, 1001, 0, 998, 999, - 1005, 1000, 1003, 1011, 1003, 1009, 1002, 1010, 0, 1001, - 1006, 1002, 1009, 1003, 1006, 1005, 1003, 1008, 1004, 1010, - - 1007, 1007, 1016, 1014, 1015, 1011, 1014, 1012, 1018, 1003, - 1011, 1003, 1009, 1016, 1010, 1012, 1019, 1015, 1020, 0, - 1022, 1050, 1018, 1019, 1020, 0, 1016, 0, 1024, 1016, - 1014, 1015, 0, 1026, 1012, 1018, 1023, 0, 1025, 1027, - 1016, 1027, 1022, 1019, 0, 1020, 1021, 1022, 1021, 1029, - 1025, 1024, 1021, 1050, 1021, 1024, 1029, 1028, 1028, 1021, - 1026, 1031, 1023, 1023, 1021, 1025, 1027, 1032, 0, 1033, - 1021, 1030, 1034, 1021, 1031, 1021, 1029, 1034, 0, 1021, - 1028, 1021, 1033, 1030, 1028, 1028, 1021, 1035, 1031, 1032, - 1036, 1021, 1043, 1040, 1032, 1037, 1033, 1038, 1030, 1041, - - 1042, 0, 1039, 1036, 1034, 1035, 1039, 1037, 1040, 1038, - 1045, 0, 1046, 1042, 1035, 1048, 1039, 1036, 1037, 1043, - 1040, 1041, 1037, 1045, 1038, 1044, 1041, 1042, 1039, 1039, - 1046, 1044, 1047, 1039, 1037, 1049, 1048, 1045, 1051, 1046, - 1052, 1054, 1048, 1039, 1055, 1056, 0, 1057, 0, 1055, - 1059, 1061, 1044, 1056, 1047, 0, 1057, 1049, 0, 1047, - 1063, 0, 1049, 1060, 1061, 1059, 0, 1052, 1062, 1064, - 1051, 1055, 1056, 1054, 1057, 1058, 1066, 1059, 1061, 1065, - 1058, 1067, 1058, 1062, 1068, 1060, 1063, 1063, 1058, 1066, - 1060, 1064, 1067, 1058, 1058, 1062, 1064, 1068, 1065, 1071, - - 1058, 1058, 1058, 1066, 1069, 1070, 1065, 1058, 1067, 1058, - 1071, 1068, 1069, 1070, 1072, 1058, 1073, 1076, 1074, 0, - 1058, 1058, 1083, 1079, 1080, 1075, 1071, 1058, 1076, 1081, - 1077, 1069, 1070, 1074, 1075, 1084, 1081, 0, 1073, 1077, - 1078, 1086, 1088, 1073, 1076, 1074, 1072, 1080, 1089, 1078, - 1079, 1080, 1075, 1085, 1083, 1087, 1081, 1077, 1090, 1084, - 1092, 1085, 1084, 1086, 1095, 1093, 1090, 1078, 1086, 1087, - 1089, 1096, 1097, 1094, 1088, 1089, 1102, 1096, 1092, 1099, - 1085, 1098, 1087, 1093, 1094, 1090, 1100, 1092, 1103, 1098, - 1097, 1101, 1093, 1100, 1104, 1103, 1095, 1109, 1096, 1097, - - 1094, 1099, 1102, 1102, 1101, 1105, 1099, 1106, 1098, 1104, - 1107, 1113, 1108, 1100, 1115, 1103, 1111, 1118, 1101, 1114, - 1117, 1104, 1108, 1105, 1113, 1106, 1114, 1111, 1116, 1109, - 1116, 1107, 1105, 1131, 1106, 1120, 1119, 1107, 1113, 1108, - 1115, 1115, 1117, 1111, 1119, 1121, 1114, 1117, 1120, 1118, - 1129, 1123, 1122, 1124, 1121, 1116, 1132, 1130, 1133, 1127, - 1128, 1138, 1120, 1119, 1122, 1131, 1138, 0, 1129, 1176, - 0, 1200, 1121, 1123, 0, 1124, 1133, 1129, 1123, 1122, - 1124, 1127, 1128, 1130, 1130, 1133, 1127, 1128, 1132, 1134, - 1135, 1137, 1143, 1138, 1140, 1141, 1176, 1140, 1200, 1142, - - 1150, 1134, 1137, 1144, 1135, 1143, 1145, 1141, 1146, 1150, - 1144, 1147, 1147, 0, 1149, 1146, 1134, 1135, 1137, 1143, - 1140, 1140, 1141, 1142, 1140, 1147, 1142, 1150, 1145, 1148, - 1144, 1151, 1152, 1145, 1149, 1146, 1153, 1160, 1147, 1147, - 1148, 1149, 1154, 1155, 1152, 1151, 0, 1158, 0, 1154, - 1156, 1157, 1161, 1166, 0, 1162, 1148, 1169, 1151, 1152, - 1158, 1162, 1156, 1160, 1160, 1163, 1164, 1167, 1153, 1154, - 1165, 1166, 1169, 1157, 1158, 1155, 1161, 1156, 1157, 1161, - 1166, 1165, 1162, 1168, 1169, 1171, 1173, 1163, 1164, 1167, - 1172, 1177, 1163, 1164, 1167, 1175, 1174, 1165, 1179, 1178, - - 1186, 1172, 1174, 1180, 1184, 1168, 1171, 1173, 1178, 1177, - 1168, 1181, 1171, 1173, 1183, 1187, 1182, 1172, 1177, 1185, - 1181, 1183, 1179, 1174, 1182, 1179, 1178, 1175, 1184, 1180, - 1180, 1184, 1186, 1185, 1188, 1189, 1190, 1191, 1181, 1193, - 0, 1183, 1198, 1182, 0, 1192, 1185, 1187, 1195, 1197, - 1196, 1199, 0, 0, 0, 0, 1197, 1189, 1190, 1196, - 0, 1201, 1189, 1190, 1202, 1203, 1188, 1192, 1208, 1191, - 1195, 1193, 1192, 1199, 1198, 1195, 1197, 1196, 1199, 1201, - 1204, 1206, 1202, 1213, 1208, 1205, 1207, 1203, 1201, 1204, - 1210, 1202, 1203, 1205, 1209, 1208, 1211, 1214, 1212, 1210, - - 1216, 1217, 0, 0, 0, 1206, 1212, 1204, 1206, 0, - 1207, 1211, 1205, 1207, 1215, 1213, 1209, 1210, 1219, 1220, - 1224, 1209, 1216, 1211, 1218, 1212, 1215, 1216, 1217, 1214, - 1221, 1219, 1218, 1223, 1220, 1225, 1228, 1229, 1224, 1221, - 1230, 1215, 1223, 1225, 1228, 1219, 1220, 1224, 1226, 1231, - 1226, 1218, 1232, 1236, 1234, 1229, 1233, 1221, 1237, 1240, - 1223, 1234, 1225, 1228, 1229, 1239, 1236, 1230, 1231, 1238, - 1237, 1242, 1244, 1245, 1232, 1226, 1231, 1240, 1233, 1232, - 1236, 1234, 1241, 1233, 1238, 1237, 1240, 1239, 1243, 1246, - 1247, 1249, 1239, 1252, 1241, 1243, 1238, 1250, 1242, 1248, - - 0, 1251, 1247, 1256, 1244, 1245, 1252, 1254, 1246, 1241, - 1248, 1256, 1253, 1249, 1257, 1243, 1246, 1247, 1249, 1255, - 1252, 1259, 1250, 1251, 1250, 1253, 1248, 1258, 1251, 1254, - 1256, 1255, 1260, 1259, 1254, 1262, 1263, 1264, 1257, 1253, - 1260, 1257, 1266, 1265, 1267, 1268, 1255, 1258, 1259, 1263, - 1269, 1266, 0, 1274, 1258, 1272, 1267, 1269, 1273, 1260, - 1264, 1265, 1262, 1263, 1264, 1270, 1268, 1275, 1276, 1266, - 1265, 1267, 1268, 1278, 1270, 1274, 1270, 1269, 1272, 1270, - 1274, 1279, 1272, 1277, 1273, 1273, 1278, 1270, 1276, 1282, - 1280, 1284, 1270, 1281, 1275, 1276, 1285, 1277, 1280, 1286, - - 1278, 1270, 1281, 1270, 1285, 1279, 1270, 1282, 1279, 1287, - 1277, 1288, 1289, 1284, 1286, 1290, 1282, 1280, 1284, 1291, - 1281, 1293, 1294, 1285, 1298, 1289, 1286, 1291, 1295, 1296, - 1297, 1290, 1302, 1288, 0, 1299, 1296, 1308, 1288, 1289, - 1302, 1287, 1290, 1308, 1294, 1305, 1291, 1298, 1293, 1294, - 1295, 1298, 1297, 1299, 1300, 1295, 1296, 1297, 1301, 1302, - 1303, 1304, 1299, 1306, 1308, 1305, 1300, 1307, 1309, 1303, - 1301, 1310, 1305, 1304, 1311, 1307, 1313, 1309, 1306, 0, - 0, 1300, 0, 0, 1303, 1301, 1311, 1303, 1304, 1312, - 1306, 1316, 1310, 1323, 1307, 1309, 1303, 1314, 1310, 1315, - - 1312, 1311, 1317, 1318, 1314, 1312, 1315, 1319, 1313, 1316, - 1324, 1318, 1320, 1321, 1317, 1321, 1312, 1324, 1316, 1322, - 1320, 1326, 1319, 1327, 1314, 1323, 1315, 1312, 1328, 1317, - 1318, 1322, 1329, 1331, 1319, 1327, 1330, 1324, 1337, 1320, - 1321, 1328, 1332, 1330, 1331, 1336, 1322, 1333, 1335, 1334, - 1327, 1329, 1337, 1326, 1334, 1328, 1335, 1338, 1336, 1329, - 1331, 1340, 1333, 1330, 1332, 1337, 1343, 1346, 1341, 1332, - 1348, 0, 1336, 1342, 1333, 1335, 0, 0, 1344, 1345, - 0, 1334, 1341, 1338, 1338, 1339, 1340, 0, 1340, 1339, - 1346, 1342, 1339, 1339, 1346, 1341, 1347, 1339, 1343, 1349, - - 1342, 1345, 1348, 1339, 1344, 1344, 1345, 1339, 1354, 1350, - 1354, 1339, 1339, 1351, 1347, 1358, 1339, 1353, 1359, 1339, - 1339, 1349, 1352, 1347, 1339, 1353, 1349, 1360, 1352, 1366, - 1339, 1350, 1354, 1356, 1339, 1354, 1350, 1354, 1355, 1351, - 1351, 1357, 1356, 1353, 1353, 1355, 1361, 1358, 1362, 1352, - 1359, 1360, 1353, 1364, 1360, 1362, 1357, 1363, 1365, 1368, - 1356, 1366, 1367, 1370, 1361, 1355, 1364, 1365, 1357, 1374, - 1369, 1373, 0, 1361, 1371, 1362, 0, 1375, 1384, 1363, - 1364, 1385, 1374, 1367, 1363, 1365, 1370, 1379, 1371, 1367, - 1370, 1368, 1369, 1373, 1376, 1376, 1374, 1369, 1373, 1377, - - 1380, 1371, 1372, 1375, 1375, 1384, 0, 1372, 1385, 1372, - 1379, 1372, 1380, 1372, 1379, 1377, 1382, 1381, 1387, 1383, - 1372, 1389, 1388, 1376, 1381, 1382, 1377, 1380, 1386, 1372, - 1392, 0, 1387, 1386, 1372, 1388, 1372, 1383, 1372, 1389, - 1372, 1390, 1391, 1382, 1381, 1387, 1383, 1391, 1389, 1388, - 1393, 1400, 1392, 1394, 1395, 1398, 1396, 1392, 1399, 1390, - 1386, 1397, 1395, 1393, 1396, 0, 1400, 1401, 1390, 1391, - 1403, 1394, 1405, 1406, 1397, 0, 1402, 1393, 1400, 1409, - 1394, 1395, 1404, 1396, 1399, 1399, 1401, 1398, 1397, 1402, - 1405, 1410, 1403, 1406, 1401, 1404, 1407, 1403, 1411, 1405, - - 1406, 1409, 1408, 1402, 1408, 1407, 1409, 1412, 1413, 1404, - 1411, 1414, 0, 1416, 1418, 1419, 1420, 1417, 1410, 1421, - 1422, 1428, 1418, 1407, 1423, 1411, 1421, 1424, 1433, 1408, - 1413, 0, 0, 1419, 1412, 1413, 1414, 1416, 1414, 1417, - 1416, 1418, 1419, 1420, 1417, 1431, 1421, 1422, 1428, 1424, - 1423, 1423, 1425, 1426, 1424, 1427, 1429, 1430, 1425, 1426, - 1433, 1427, 1440, 1429, 1432, 1434, 1437, 1430, 1435, 1431, - 1439, 1432, 1431, 1436, 1440, 1437, 1441, 1442, 0, 1425, - 1426, 1447, 1427, 1429, 1430, 1444, 1435, 1434, 1443, 1440, - 1441, 1432, 1434, 1437, 1439, 1435, 1446, 1439, 1436, 1442, - - 1436, 1443, 1445, 1441, 1442, 1447, 1448, 1444, 1447, 1449, - 1450, 1451, 1444, 1452, 0, 1443, 1454, 1456, 1446, 1453, - 1451, 1445, 1457, 1446, 1460, 1458, 1459, 0, 1448, 1445, - 1454, 1464, 1450, 1448, 1452, 1449, 1449, 1450, 1451, 1453, - 1452, 1461, 1462, 1454, 1463, 1468, 1453, 1458, 1459, 1456, - 1462, 1474, 1458, 1459, 1457, 1465, 1460, 1466, 1464, 1461, - 1463, 1469, 1465, 1470, 1466, 1471, 1472, 1468, 1461, 1462, - 1469, 1463, 1468, 1472, 1473, 1475, 1476, 1471, 1473, 1477, - 1470, 1479, 1465, 1474, 1466, 1480, 0, 1483, 1469, 1482, - 1470, 1480, 1471, 1472, 0, 1477, 1481, 1476, 1480, 1485, - - 0, 1473, 1481, 1476, 1486, 0, 1477, 1475, 1484, 1481, - 1488, 1482, 1480, 1479, 1485, 1484, 1482, 1486, 1480, 1483, - 1489, 1487, 1490, 1481, 1490, 1491, 1485, 1489, 1492, 1481, - 1487, 1486, 1493, 1494, 1491, 1484, 1488, 1488, 1495, 1496, - 1499, 1493, 1495, 1498, 1500, 1502, 1503, 1489, 1487, 1490, - 1492, 1498, 1491, 1499, 1502, 1492, 1504, 1501, 1500, 1493, - 1494, 1496, 1501, 1505, 1503, 1495, 1496, 1499, 1506, 1509, - 1498, 1500, 1502, 1503, 1507, 1504, 1505, 1507, 1508, 1511, - 1506, 1508, 1510, 1504, 1513, 0, 1507, 1509, 1514, 1501, - 1505, 1515, 1511, 1517, 1516, 1506, 1509, 1521, 1517, 1514, - - 1508, 1507, 0, 1518, 1507, 1508, 1511, 1510, 1508, 1510, - 1516, 1518, 1519, 1519, 1515, 1514, 1513, 1520, 1515, 1521, - 1522, 1516, 1524, 1523, 1521, 1517, 1520, 1525, 1527, 1526, - 1518, 1524, 1530, 1529, 1525, 1527, 1532, 1536, 1533, 1519, - 0, 1530, 1522, 1531, 1520, 1523, 1529, 1522, 1534, 1524, - 1523, 1526, 1531, 1537, 1525, 1527, 1526, 1534, 1535, 1530, - 1529, 1533, 1532, 1532, 1539, 1533, 1535, 1538, 1537, 1536, - 1531, 1540, 1539, 1543, 1541, 1534, 1542, 1544, 1538, 1548, - 1537, 1543, 1545, 1546, 1540, 1535, 1541, 1547, 1542, 1549, - 1551, 1539, 1548, 1552, 1538, 1556, 1547, 1557, 1540, 1544, - - 1543, 1541, 1545, 1542, 1544, 1546, 1548, 1550, 1551, 1545, - 1546, 1549, 1553, 1550, 1547, 1554, 1549, 1551, 1555, 1552, - 1552, 1556, 1556, 1558, 1553, 1555, 1560, 1559, 0, 1557, - 1561, 1564, 1563, 1554, 1550, 1562, 1566, 1564, 1565, 1553, - 1559, 1567, 1554, 1563, 1568, 1555, 0, 0, 1569, 0, - 0, 1570, 1560, 1560, 1559, 1558, 1562, 1561, 1564, 1563, - 1565, 1572, 1562, 1573, 1574, 1565, 1576, 1579, 1566, 1583, - 1570, 1575, 1570, 1567, 1569, 1569, 1568, 1570, 1570, 1577, - 1575, 1576, 1574, 1578, 0, 1580, 1573, 1579, 1572, 1581, - 1573, 1574, 1577, 1576, 1579, 1578, 1581, 1570, 1575, 1570, - - 1582, 1583, 1584, 1587, 1585, 1586, 1577, 1589, 1587, 1588, - 1578, 1580, 1580, 1586, 1588, 1590, 1581, 1585, 1591, 1582, - 1592, 1594, 1590, 1600, 1584, 1593, 0, 1582, 1592, 1584, - 1589, 1585, 1586, 1593, 1589, 1587, 1595, 1602, 1596, 1594, - 1601, 1588, 1590, 1597, 1591, 1591, 1596, 1592, 1594, 1598, - 1599, 1597, 1593, 1604, 1607, 1600, 1598, 1603, 1595, 1599, - 1604, 1605, 1601, 1595, 1609, 1596, 1603, 1601, 1610, 1602, - 1597, 1606, 1606, 1605, 1608, 1611, 1598, 1599, 1612, 1613, - 1604, 1614, 1608, 1611, 1603, 1609, 1607, 1613, 1605, 1614, - 1620, 1609, 1619, 0, 1621, 1615, 1612, 1617, 1606, 1616, - - 1610, 1608, 1611, 1615, 1619, 1612, 1613, 1616, 1614, 1618, - 1617, 1625, 1622, 1624, 1626, 1618, 1620, 1620, 1621, 1619, - 1622, 1621, 1615, 1623, 1617, 1627, 1616, 1631, 1624, 1629, - 1628, 1623, 1630, 1639, 1632, 0, 1618, 1637, 1625, 1622, - 1624, 1626, 1639, 1629, 1630, 1631, 1640, 1627, 1632, 1647, - 1623, 1635, 1627, 1628, 1631, 1635, 1629, 1628, 1638, 1630, - 1639, 1632, 1641, 1637, 1637, 1642, 1645, 1643, 1635, 1646, - 1640, 1650, 1644, 1640, 1643, 1648, 1635, 1642, 1635, 1651, - 1638, 1647, 1635, 1644, 1641, 1638, 1649, 1648, 1652, 1641, - 1656, 1646, 1642, 1645, 1643, 1635, 1646, 1653, 1654, 1644, - - 1649, 1651, 1648, 1650, 1658, 1654, 1651, 1655, 1656, 0, - 1659, 1652, 1657, 1649, 1661, 1652, 1655, 1656, 1663, 1657, - 1653, 1664, 1665, 1661, 1653, 1654, 1666, 1664, 1667, 1670, - 1672, 1668, 1673, 0, 1655, 1674, 1658, 1659, 1668, 1657, - 1675, 1661, 0, 0, 1665, 1678, 1674, 1681, 1664, 1665, - 1663, 1675, 1666, 1666, 1672, 1676, 1670, 1672, 1668, 1673, - 1667, 1680, 1674, 1683, 1679, 1681, 1676, 1675, 1680, 1678, - 1679, 1682, 1678, 1684, 1681, 1685, 1686, 1687, 1682, 1688, - 1689, 1685, 1676, 1690, 1686, 1684, 1692, 1691, 1680, 1683, - 1683, 1679, 1688, 1696, 1695, 1692, 1693, 0, 1682, 1687, - - 1684, 1695, 1685, 1686, 1687, 1691, 1688, 1698, 1693, 1690, - 1690, 1697, 1689, 1692, 1691, 1694, 1698, 1694, 1699, 1696, - 1696, 1695, 1701, 1693, 1697, 1700, 1703, 1702, 0, 1704, - 1705, 1706, 1707, 1703, 1698, 1705, 1709, 1700, 1697, 1706, - 1699, 1708, 1694, 1710, 1709, 1699, 1712, 1714, 1707, 1701, - 1702, 0, 1700, 1703, 1702, 1704, 1704, 1705, 1706, 1707, - 1716, 1713, 1715, 1709, 1708, 1710, 1713, 1717, 1708, 0, - 1710, 1714, 1718, 1712, 1714, 1719, 1715, 1721, 1717, 1724, - 1723, 1718, 1716, 1720, 1720, 1726, 1725, 1716, 1719, 1715, - 1721, 1720, 1726, 1713, 1717, 1722, 1727, 1722, 1723, 1718, - - 1729, 1731, 1719, 1732, 1721, 1724, 1724, 1723, 1725, 1728, - 1720, 1720, 1726, 1725, 1735, 1733, 1728, 1730, 1727, 1734, - 1737, 1732, 1722, 1727, 1729, 1730, 1734, 1729, 1731, 1736, - 1732, 1738, 1739, 1740, 1742, 1743, 1728, 1733, 1738, 1735, - 1744, 1735, 1733, 1746, 1730, 1745, 1734, 1742, 1744, 0, - 1747, 1736, 1737, 1745, 1749, 1740, 1736, 1751, 1738, 1752, - 1740, 1742, 1743, 1750, 1739, 1746, 1750, 1744, 1755, 1753, - 1746, 1747, 1745, 1756, 0, 1757, 1749, 1747, 1754, 1758, - 1755, 1749, 1753, 1751, 1751, 1752, 1752, 1754, 1758, 1759, - 1750, 1760, 1763, 1762, 0, 1755, 1753, 1756, 1760, 1764, - - 1756, 1757, 1757, 1765, 1759, 1754, 1758, 1761, 1762, 1770, - 1761, 1767, 1769, 1768, 1769, 1771, 1759, 1776, 1760, 1765, - 1762, 1764, 1761, 1773, 1763, 1772, 1764, 1765, 1772, 1767, - 1765, 1761, 1774, 1770, 1761, 1768, 1770, 1761, 1767, 1769, - 1768, 1775, 1771, 1776, 1776, 1777, 1765, 1778, 1779, 1761, - 1781, 1780, 1772, 1782, 1785, 1773, 1786, 1784, 1787, 1781, - 1783, 1782, 1789, 1775, 1774, 1780, 1792, 1783, 1775, 1788, - 1779, 1777, 1777, 1791, 1794, 1779, 1793, 1781, 1780, 1778, - 1782, 1784, 0, 1794, 1784, 1790, 1785, 1783, 1786, 1790, - 1787, 1788, 1795, 1792, 1789, 1791, 1788, 1796, 1793, 1795, - - 1791, 1794, 1797, 1793, 1800, 1798, 1803, 1799, 1801, 1796, - 1802, 1797, 1790, 1798, 1799, 1803, 1804, 1800, 1804, 1795, - 1807, 1801, 1805, 1802, 1796, 1806, 1808, 1810, 1807, 1797, - 1812, 1800, 1798, 1803, 1799, 1801, 1811, 1802, 1813, 0, - 1822, 1814, 1810, 1804, 1812, 1805, 1808, 1807, 1814, 1805, - 1806, 1811, 1806, 1808, 1810, 1815, 1817, 1812, 1816, 1820, - 1818, 0, 1819, 1811, 1823, 1816, 1815, 1822, 1814, 1817, - 1813, 1823, 1824, 0, 1826, 1825, 1829, 1820, 1818, 1829, - 1827, 0, 1815, 1817, 1818, 1816, 1820, 1818, 1819, 1819, - 1825, 1823, 1827, 1828, 1824, 1830, 1831, 1832, 1833, 1824, - - 1826, 1826, 1825, 1829, 1830, 1818, 1828, 1827, 1832, 1834, - 1833, 0, 1835, 1842, 1831, 1835, 1836, 1843, 1844, 1840, - 1828, 1832, 1830, 1831, 1832, 1833, 1838, 1836, 1840, 1834, - 1835, 1838, 1841, 1845, 1841, 1832, 1834, 1842, 1838, 1835, - 1842, 1846, 1835, 1836, 1843, 1844, 1840, 1847, 1845, 1848, - 1846, 1849, 1850, 1838, 1851, 1852, 1855, 1853, 1838, 1841, - 1845, 1848, 1851, 1854, 1856, 1857, 1850, 1853, 1846, 1863, - 1856, 1847, 1863, 1865, 1847, 1860, 1848, 1852, 1849, 1850, - 1855, 1851, 1852, 1855, 1853, 1854, 1858, 1857, 1859, 1861, - 1854, 1856, 1857, 1860, 1858, 1866, 1863, 1861, 1869, 1859, - - 1862, 1864, 1860, 1862, 1867, 1865, 1873, 1868, 1870, 1872, - 1871, 1873, 1869, 1858, 1868, 1859, 1861, 1870, 1862, 1864, - 1872, 1874, 1866, 1871, 1867, 1869, 1875, 1862, 1864, 1880, - 1862, 1867, 1903, 1881, 1868, 1870, 1872, 1871, 1873, 1882, - 1878, 1875, 1878, 1874, 1883, 1879, 0, 1884, 1874, 1885, - 1882, 1884, 0, 1875, 1879, 1880, 1880, 1881, 1888, 1903, - 1881, 1886, 1883, 1885, 1886, 1889, 1882, 1878, 1887, 0, - 1890, 1883, 1879, 1884, 1884, 1885, 1885, 1891, 1884, 1886, - 1901, 1887, 1888, 1892, 1893, 1888, 1891, 1889, 1886, 1892, - 1885, 1886, 1889, 1893, 1894, 1887, 1890, 1890, 1898, 1894, - - 1896, 1899, 1897, 1898, 1891, 1900, 1902, 1904, 1905, 1906, - 1892, 1893, 1901, 1896, 1897, 1902, 1907, 1908, 1900, 0, - 1913, 0, 1906, 1899, 1910, 1898, 1894, 1896, 1899, 1897, - 1905, 1910, 1900, 1902, 1911, 1905, 1906, 1912, 1908, 1904, - 1914, 1911, 1925, 1916, 1908, 0, 1918, 1915, 1907, 1920, - 1912, 1910, 1913, 1915, 1914, 1921, 1926, 1920, 1922, 1923, - 1925, 1911, 1924, 1921, 1912, 1918, 1922, 1914, 1929, 1925, - 1926, 1915, 1927, 1918, 1915, 1916, 1920, 1928, 1923, 1930, - 1915, 1929, 1921, 1926, 1924, 1922, 1923, 1931, 1932, 1924, - 1927, 1928, 1930, 1933, 1934, 1929, 1935, 1936, 0, 1927, - - 1937, 1939, 1938, 1940, 1928, 1941, 1930, 1937, 1931, 1939, - 1935, 1938, 1942, 1947, 1931, 1950, 0, 0, 1934, 1941, - 1932, 1934, 1944, 1935, 1936, 1933, 1943, 1937, 1939, 1938, - 1940, 1943, 1941, 1944, 1945, 1931, 1949, 1950, 1948, 1951, - 1947, 0, 1950, 1945, 1942, 1948, 1951, 1952, 1953, 1944, - 1954, 1955, 1961, 1943, 1960, 1955, 1957, 1959, 0, 1949, - 1964, 1945, 1968, 1949, 0, 1948, 1951, 1957, 1954, 1952, - 1953, 1962, 1960, 1959, 1952, 1953, 1961, 1954, 1955, 1961, - 1957, 1960, 1965, 1957, 1959, 1963, 1962, 1964, 1966, 1968, - 1965, 1967, 1969, 1970, 1957, 1972, 1971, 1963, 1962, 1967, - - 1976, 1973, 1974, 1966, 1979, 1978, 1970, 1976, 1975, 1965, - 1972, 1979, 1963, 1978, 1969, 1966, 1971, 1974, 1967, 1969, - 1970, 1973, 1972, 1971, 1975, 1980, 1981, 1976, 1973, 1974, - 0, 1979, 1978, 1982, 1983, 1975, 1984, 1986, 1985, 1987, - 0, 1981, 1982, 1990, 1986, 1989, 1991, 1993, 0, 1994, - 1992, 0, 0, 1981, 1995, 1983, 1997, 1980, 1991, 1996, - 1982, 1983, 1985, 1984, 1986, 1985, 1987, 1989, 1992, 1995, - 0, 1998, 1989, 1991, 2002, 1990, 1994, 1992, 1998, 1993, - 1997, 1995, 1999, 1997, 1996, 2000, 1996, 1999, 2001, 2003, - 2004, 2005, 2006, 0, 2000, 0, 2002, 2001, 1998, 2007, - - 2008, 2002, 2013, 2010, 2006, 2014, 2005, 2009, 2004, 1999, - 2010, 2003, 2000, 2012, 2013, 2001, 2003, 2004, 2005, 2006, - 2009, 2007, 2008, 2015, 2011, 2009, 2007, 2008, 0, 2013, - 2010, 2011, 2014, 2016, 2009, 2012, 2019, 2018, 2022, 2016, - 2012, 2020, 2021, 2026, 2019, 2022, 2011, 2009, 2018, 2020, - 2023, 2011, 2025, 2021, 2024, 2015, 2024, 2027, 2011, 2028, - 2016, 2029, 2034, 2019, 2018, 2022, 2028, 2024, 2020, 2021, - 2026, 2030, 2035, 2036, 2031, 2023, 2032, 2023, 2025, 2025, - 2031, 2024, 2032, 2024, 2027, 2033, 2028, 2037, 2029, 2034, - 2039, 2033, 2041, 2040, 2044, 2035, 2042, 2030, 2030, 2035, - - 2042, 2031, 2040, 2032, 2045, 2036, 2045, 2043, 2046, 2047, - 2048, 2037, 2033, 0, 2037, 2050, 2044, 2048, 2049, 2053, - 2040, 2044, 2039, 2042, 2041, 2043, 2051, 2052, 2054, 0, - 2055, 2045, 2046, 2052, 2043, 2046, 2047, 2048, 2051, 2056, - 2049, 2053, 2050, 2057, 2059, 2049, 2053, 2062, 0, 0, - 2054, 2059, 0, 2051, 2052, 2054, 2055, 2055, 2058, 2058, - 2058, 2056, 2061, 2060, 2065, 2058, 2056, 2063, 2069, 2061, - 2064, 2059, 2060, 2058, 2063, 2057, 2066, 2064, 2068, 2062, - 2071, 2069, 2074, 2068, 2065, 2058, 2058, 2058, 2070, 2061, - 2060, 2065, 2058, 2072, 2063, 2069, 2073, 2064, 2066, 2075, - - 2070, 2080, 0, 2066, 2076, 2071, 2077, 2071, 2073, 2072, - 2068, 2076, 2079, 2078, 2074, 2070, 2082, 2075, 2079, 2077, - 2072, 2078, 2083, 2073, 2081, 2081, 2075, 2084, 2080, 2083, - 2085, 2076, 2084, 2077, 2086, 2087, 2091, 2088, 2094, 2079, - 2078, 2093, 2082, 2082, 2088, 2092, 2097, 2092, 2096, 2083, - 2098, 2081, 2097, 0, 2084, 0, 2085, 2085, 2103, 2093, - 2101, 2086, 2087, 2091, 2088, 2094, 2096, 2102, 2093, 2100, - 2099, 2101, 2092, 2097, 2105, 2096, 2099, 2100, 2104, 2106, - 2102, 2110, 2098, 2109, 2104, 2103, 2105, 2101, 2114, 2107, - 2108, 2108, 2111, 2111, 2102, 2118, 2100, 2099, 2116, 2106, - - 2112, 2105, 2115, 2119, 2123, 2104, 2106, 2107, 2110, 2109, - 2109, 2112, 2120, 2124, 2117, 2118, 2107, 2108, 2122, 2111, - 2114, 2117, 2118, 2131, 2115, 2125, 2122, 2112, 2126, 2115, - 2116, 2127, 0, 2130, 2138, 2119, 2123, 2120, 2131, 2120, - 2124, 2117, 2128, 2127, 2132, 2122, 2126, 2125, 2129, 2128, - 2131, 2135, 2125, 2133, 2137, 2126, 2129, 2130, 2127, 2136, - 2130, 2137, 2133, 2134, 2134, 2141, 2138, 2140, 2132, 2128, - 2139, 2132, 2141, 2143, 2146, 2129, 2142, 2135, 2135, 2146, - 2133, 2137, 2136, 2147, 2145, 2139, 2136, 2148, 2142, 2143, - 2134, 2145, 2141, 2155, 2150, 2149, 2143, 2139, 2149, 2140, - - 2143, 2146, 2150, 2142, 2153, 2147, 2151, 2154, 2156, 2157, - 2147, 2145, 2153, 2158, 2148, 2160, 2143, 2162, 2151, 2155, - 2155, 2150, 2149, 2159, 0, 2166, 0, 2157, 0, 2156, - 2154, 2153, 2161, 2151, 2154, 2156, 2157, 2161, 2160, 2163, - 2158, 2159, 2160, 2164, 2162, 2163, 2165, 2166, 2161, 2170, - 2159, 2167, 2166, 2168, 2165, 2169, 2164, 2172, 2167, 2161, - 2168, 2173, 2169, 2171, 2161, 2174, 2163, 2175, 2177, 2172, - 2164, 2176, 2171, 2165, 0, 2179, 2183, 2185, 2167, 2174, - 2168, 2170, 2169, 2173, 2172, 2187, 2182, 2189, 2173, 2191, - 2171, 2177, 2174, 2179, 2175, 2177, 2180, 2176, 2176, 2181, - - 2186, 2180, 2179, 2183, 2185, 2186, 2181, 2192, 2182, 2190, - 2190, 2191, 2180, 2182, 2193, 2195, 2191, 2187, 2196, 2189, - 2197, 2200, 2192, 2180, 2198, 2199, 2181, 2199, 2180, 2202, - 2195, 2203, 2186, 2201, 2192, 2197, 2190, 2204, 2201, 2205, - 2206, 2196, 2195, 2203, 2215, 2196, 2193, 2197, 2206, 2207, - 2198, 2198, 2199, 2200, 2209, 2208, 2207, 2211, 2203, 2204, - 2201, 2202, 2212, 2213, 2204, 2221, 2205, 2206, 2216, 2209, - 2212, 2215, 2211, 2217, 2218, 2220, 2207, 2208, 2219, 2222, - 2223, 2209, 2208, 2224, 2211, 2213, 2226, 2223, 0, 2212, - 2213, 2222, 2216, 2225, 2228, 2216, 2227, 2221, 0, 2217, - - 2217, 2218, 2220, 2230, 2219, 2219, 2222, 2223, 2226, 2233, - 2241, 2231, 2228, 2226, 2225, 2224, 2231, 2227, 2234, 2236, - 2225, 2228, 2235, 2227, 2237, 2230, 2242, 2239, 2235, 2240, - 2230, 2246, 2241, 2233, 2236, 0, 2233, 2241, 2244, 2243, - 2245, 2234, 2239, 2231, 2240, 2234, 2236, 2247, 2252, 2235, - 2237, 2237, 2248, 2242, 2239, 2246, 2240, 2243, 2246, 2248, - 2244, 2250, 2245, 2249, 2251, 2244, 2243, 2245, 2255, 2253, - 2250, 2254, 2251, 0, 2247, 2256, 2257, 2258, 2262, 2248, - 2252, 2249, 2259, 2263, 2256, 2266, 2258, 2262, 2250, 2264, - 2249, 2251, 2253, 2254, 2257, 2259, 2253, 2261, 2254, 2265, - - 2255, 2263, 2256, 2257, 2258, 2262, 2265, 2264, 2261, 2259, - 2263, 2266, 2266, 2267, 2268, 2269, 2264, 2270, 2271, 2274, - 0, 2269, 0, 2261, 2261, 2276, 2265, 2277, 2283, 2268, - 2285, 2267, 2271, 0, 0, 2261, 2278, 2279, 2277, 2270, - 2267, 2268, 2269, 2281, 2270, 2271, 2274, 2278, 2279, 2276, - 2286, 2284, 2276, 2282, 2277, 2281, 2285, 2285, 2287, 2289, - 2283, 2284, 2288, 2278, 2279, 2290, 2282, 2293, 2289, 2291, - 2281, 2287, 2294, 2298, 2297, 2286, 2301, 2286, 2284, 0, - 2282, 2301, 2300, 2288, 2299, 2287, 2289, 2296, 2291, 2288, - 2303, 2296, 2290, 2302, 2293, 2297, 2291, 2299, 2294, 2294, - - 2302, 2297, 2300, 2301, 2304, 2298, 2306, 2305, 2307, 2300, - 2308, 2299, 2304, 2305, 2296, 0, 2303, 2303, 2310, 2310, - 2302, 2306, 2308, 2307, 2311, 2309, 2312, 2313, 0, 2317, - 2304, 2304, 2313, 2306, 2305, 2307, 2317, 2308, 2312, 2304, - 2309, 2320, 2311, 2314, 0, 2310, 2318, 2314, 2319, 2326, - 2318, 2311, 2309, 2312, 2315, 2315, 2317, 2321, 2315, 2313, - 2322, 2324, 2323, 2319, 2325, 2327, 2321, 2322, 2320, 0, - 2314, 2315, 2327, 2318, 2329, 2319, 2326, 2330, 2332, 2315, - 0, 2315, 2315, 2324, 2321, 2315, 2323, 2322, 2324, 2323, - 2325, 2325, 2327, 2333, 2331, 2341, 2329, 2336, 2315, 2338, - - 2332, 2329, 2330, 2331, 2330, 2332, 2342, 2339, 2338, 2343, - 2341, 2344, 2345, 2333, 2346, 2336, 2349, 2343, 2351, 2345, - 2333, 2331, 2341, 2344, 2336, 2339, 2338, 2350, 2347, 2352, - 2352, 2342, 0, 2342, 2339, 2347, 2343, 2353, 2344, 2345, - 2350, 2349, 2354, 2349, 2356, 2351, 2346, 2361, 2357, 2358, - 2360, 2359, 0, 0, 2350, 2347, 2352, 2360, 2358, 2353, - 2359, 2362, 0, 2371, 2353, 2364, 2356, 2354, 2363, 2354, - 2357, 2356, 2366, 2376, 2369, 2357, 2358, 2360, 2359, 2361, - 2364, 2365, 2363, 2362, 2372, 2368, 2365, 2369, 2362, 2370, - 2371, 2366, 2364, 2368, 2374, 2363, 2375, 2377, 2373, 2366, - - 2379, 2369, 2378, 2375, 2370, 2376, 2374, 2380, 2381, 2382, - 2372, 2372, 2368, 2365, 2373, 2384, 2370, 2381, 2383, 2377, - 2386, 2374, 2387, 2375, 2377, 2373, 2383, 2378, 2385, 2378, - 2389, 2390, 2379, 2388, 2448, 2381, 2392, 2383, 0, 2380, - 2390, 2382, 2384, 2385, 2394, 2383, 2386, 2386, 2387, 2387, - 2395, 2388, 2389, 2383, 2398, 2385, 2395, 2389, 2390, 2392, - 2388, 2393, 2396, 2392, 2393, 2397, 2448, 2396, 2399, 2394, - 2401, 2394, 2398, 0, 2402, 2408, 2403, 2395, 2404, 2393, - 2397, 2398, 2406, 2399, 2401, 2409, 0, 2407, 2393, 2402, - 0, 2393, 2397, 2408, 2396, 2399, 2406, 2401, 2403, 2407, - - 2404, 2402, 2408, 2403, 2410, 2404, 2407, 2411, 2412, 2406, - 2413, 2415, 2409, 2410, 2407, 2416, 2411, 2412, 2414, 2417, - 2414, 2413, 2421, 0, 2415, 2419, 2407, 2416, 2420, 2421, - 2424, 2410, 2422, 0, 2411, 2412, 2423, 2413, 2415, 0, - 2419, 2417, 2416, 2420, 2425, 2414, 2417, 2428, 2424, 2421, - 2432, 2430, 2419, 2425, 2422, 2420, 2436, 2424, 2423, 2422, - 2428, 2431, 2432, 2423, 2433, 2431, 2435, 2434, 2428, 2434, - 0, 2425, 2430, 2433, 2428, 2438, 2439, 2432, 2430, 2437, - 2444, 2440, 2441, 2436, 2435, 2439, 2443, 2428, 2431, 2440, - 2442, 2433, 2444, 2435, 2434, 2451, 2449, 2437, 2452, 2462, - - 2443, 2449, 2438, 2439, 2445, 2441, 2437, 2444, 2440, 2441, - 2447, 2445, 2442, 2443, 2450, 2453, 2455, 2442, 2447, 2450, - 2460, 2456, 2458, 2449, 2460, 2461, 2462, 2451, 2456, 2458, - 2452, 2445, 2465, 2464, 2461, 2455, 2463, 2447, 2466, 2453, - 2467, 2471, 2453, 2455, 2468, 2469, 2450, 2460, 2456, 2458, - 2463, 2464, 2461, 2468, 2475, 2467, 2472, 2474, 2476, 2465, - 2464, 2463, 2463, 2463, 2466, 2466, 2469, 2467, 2472, 2473, - 2477, 2468, 2469, 2471, 2478, 2480, 2473, 2463, 2482, 2474, - 2475, 2475, 2481, 2472, 2474, 2476, 2483, 2487, 2463, 2481, - 2486, 2487, 2477, 2483, 2489, 2488, 2473, 2477, 2480, 0, - - 0, 2482, 2480, 2489, 2490, 2482, 2478, 2488, 2485, 2481, - 2485, 2491, 2486, 2483, 2487, 2494, 2492, 2486, 2493, 2495, - 2491, 2489, 2488, 2496, 2495, 2493, 2490, 2492, 2497, 2498, - 2499, 2490, 2501, 2501, 2508, 2485, 2504, 2494, 2491, 2500, - 2502, 2498, 2494, 2492, 2504, 2493, 2495, 2503, 2500, 2502, - 2496, 2497, 2499, 2505, 2506, 2497, 2498, 2499, 2510, 2501, - 2507, 2508, 2503, 2504, 2511, 2512, 2500, 2502, 2506, 2507, - 2513, 0, 2511, 2512, 2503, 2505, 2516, 2510, 2513, 2514, - 2505, 2506, 2517, 2514, 2516, 2510, 2515, 2507, 2517, 2515, - 2518, 2511, 2512, 2519, 2520, 2522, 2521, 2513, 2524, 2519, - - 0, 2526, 0, 2516, 2529, 2518, 2514, 2531, 2527, 2517, - 2524, 2528, 2530, 2515, 2521, 2526, 2534, 2518, 2532, 2530, - 2519, 2527, 2533, 2521, 2536, 2524, 2520, 2522, 2526, 2529, - 2534, 2529, 2528, 2535, 2531, 2527, 2535, 2536, 2528, 2530, - 2532, 2537, 2539, 2534, 2538, 2532, 2533, 2540, 2541, 2533, - 2542, 2536, 2543, 2544, 2547, 2537, 2545, 0, 2548, 2545, - 2535, 2549, 2542, 2550, 2543, 2552, 2553, 2544, 2537, 2539, - 2538, 2538, 2540, 2549, 2540, 2541, 2554, 2542, 2556, 2543, - 2544, 2547, 2545, 2545, 2548, 2548, 2545, 2560, 2549, 2550, - 2550, 2551, 2552, 2553, 2551, 2557, 2559, 2558, 2554, 2562, - - 2556, 2560, 2557, 2554, 2558, 2556, 2563, 2564, 2565, 2551, - 2566, 2559, 2567, 2568, 2560, 2564, 2569, 2570, 2551, 2566, - 2571, 2551, 2557, 2559, 2558, 2568, 2562, 2573, 2572, 2574, - 0, 2575, 2576, 2563, 2564, 2565, 2574, 2566, 2569, 2567, - 2568, 2572, 2576, 2569, 2570, 2573, 2577, 2571, 2578, 2581, - 2582, 2584, 2579, 2587, 2573, 2572, 2574, 2575, 2575, 2576, - 2579, 2578, 2583, 2585, 2586, 0, 2598, 2589, 2588, 2590, - 2583, 2581, 2585, 2577, 2587, 2578, 2581, 2582, 2584, 2579, - 2587, 2593, 2589, 0, 2597, 0, 2586, 2592, 2595, 2583, - 2585, 2586, 2588, 2589, 2589, 2588, 2590, 2591, 2598, 2592, - - 2595, 2601, 2596, 2602, 2603, 2591, 2593, 2602, 2593, 2589, - 2596, 2597, 2600, 2601, 2592, 2595, 2603, 2604, 2605, 2600, - 2607, 2609, 2614, 2610, 2591, 2606, 2611, 2607, 2601, 2596, - 2602, 2603, 0, 2606, 2608, 2615, 0, 2612, 2611, 2600, - 2604, 2608, 2615, 2609, 2604, 2605, 2610, 2607, 2609, 2614, - 2610, 2612, 2606, 2611, 2616, 2617, 2618, 2619, 2620, 2621, - 2621, 2608, 2615, 2612, 2612, 2618, 2619, 2622, 2617, 2623, - 2620, 2679, 2624, 2629, 2616, 2627, 0, 2628, 2612, 2630, - 0, 2616, 2617, 2618, 2619, 2620, 2621, 2623, 2625, 2631, - 0, 0, 2628, 2622, 2622, 2629, 2623, 2624, 2679, 2624, - - 2629, 2630, 2635, 2625, 2628, 2625, 2630, 2627, 2632, 2633, - 2632, 2631, 2625, 2634, 2642, 2625, 2631, 2636, 2643, 2634, - 2635, 2637, 2637, 2633, 2639, 2640, 2642, 2641, 2644, 2635, - 2625, 2645, 2625, 2647, 2648, 2632, 2633, 2645, 0, 2636, - 2634, 2642, 2649, 2646, 2636, 2654, 2639, 2640, 2637, 2641, - 2643, 2639, 2640, 2651, 2641, 2646, 2648, 2650, 2645, 2650, - 2644, 2648, 2652, 2654, 2649, 2647, 2653, 2651, 2659, 2649, - 2646, 0, 2654, 2653, 2655, 2658, 2656, 2657, 2660, 0, - 2651, 2666, 2661, 2668, 2650, 2667, 2652, 0, 2658, 2652, - 2663, 2665, 2655, 2653, 2656, 2657, 0, 2663, 2665, 2666, - - 2659, 2655, 2658, 2656, 2657, 2661, 2669, 2670, 2666, 2661, - 2660, 2667, 2667, 2671, 2669, 2668, 2673, 2663, 2665, 2672, - 0, 0, 2674, 2670, 2675, 2677, 2675, 2681, 2678, 0, - 2682, 2675, 2669, 2669, 2670, 2680, 2677, 2672, 2671, 2678, - 2671, 2669, 2673, 2673, 2674, 2681, 2672, 2680, 2682, 2674, - 2683, 2675, 2677, 2675, 2681, 2678, 2684, 2682, 2686, 2687, - 2688, 2689, 2680, 0, 2693, 2691, 2694, 2695, 2692, 2683, - 2687, 2693, 2688, 2686, 2696, 2697, 2689, 2683, 2684, 2698, - 2704, 2699, 2695, 2684, 2694, 2686, 2687, 2688, 2689, 2691, - 2692, 2693, 2691, 2694, 2695, 2692, 2701, 2702, 2703, 2705, - - 2706, 2696, 2697, 2707, 0, 0, 2698, 2699, 2699, 2708, - 0, 2709, 2704, 2710, 0, 2711, 2712, 2715, 2706, 2714, - 2703, 2702, 2708, 2701, 2702, 2703, 2713, 2706, 2710, 2712, - 2707, 2705, 2717, 2719, 2713, 2716, 2708, 2709, 2709, 2720, - 2710, 2711, 2711, 2712, 2721, 2714, 2714, 2722, 2716, 2715, - 2723, 2726, 2724, 2713, 2717, 2725, 2719, 2727, 2726, 2717, - 2719, 2728, 2716, 2720, 2731, 2739, 2720, 2729, 2732, 2722, - 2724, 2721, 2723, 2725, 2722, 2732, 2733, 2723, 2726, 2724, - 2727, 2729, 2725, 2733, 2727, 2734, 2731, 2735, 2728, 2737, - 2736, 2731, 2734, 2738, 2729, 2732, 2737, 2739, 2740, 2742, - - 2735, 2741, 2744, 2733, 2743, 0, 2754, 2749, 2751, 2755, - 2745, 2744, 2734, 2736, 2735, 2738, 2737, 2736, 2745, 2740, - 2738, 2742, 2747, 2751, 2746, 2740, 2742, 2741, 2741, 2744, - 2743, 2743, 2746, 2748, 2749, 2751, 2752, 2745, 2754, 2748, - 2753, 2755, 2756, 2757, 2747, 2761, 2759, 2752, 2763, 2747, - 0, 2746, 2762, 2764, 0, 2765, 2775, 0, 2761, 2767, - 2748, 2756, 2753, 2752, 2759, 2762, 2768, 2753, 2757, 2756, - 2757, 2769, 2761, 2759, 2763, 2763, 2771, 2764, 2768, 2762, - 2764, 2765, 2765, 2767, 2770, 2770, 2767, 2774, 2775, 2776, - 2777, 2778, 0, 2768, 2782, 2769, 2784, 2779, 2769, 2786, - - 2790, 0, 2771, 2771, 2776, 2784, 2791, 2791, 2792, 2778, - 2774, 2770, 2786, 2798, 2774, 2800, 2776, 2777, 2778, 2779, - 2787, 2782, 2790, 2784, 2779, 0, 2786, 2790, 2793, 2796, - 2794, 2787, 2797, 2791, 2792, 2792, 2794, 2793, 2802, 2803, - 2798, 2804, 2800, 0, 2813, 2806, 2803, 2787, 2811, 2805, - 2806, 2796, 2807, 2809, 2797, 2793, 2796, 2794, 2810, 2797, - 2805, 2809, 2812, 2811, 2822, 2816, 2803, 2804, 2804, 2817, - 2802, 2813, 2806, 2815, 2807, 2811, 2805, 2812, 2818, 2807, - 2809, 2820, 2810, 2816, 2815, 2810, 2819, 2823, 2824, 2812, - 2817, 2822, 2816, 2820, 2825, 2819, 2817, 2826, 2832, 2827, - - 2815, 2828, 2828, 2829, 0, 2823, 2824, 2827, 2820, 2828, - 2818, 2831, 2829, 2819, 2823, 2824, 2835, 2833, 2825, 2836, - 2837, 2825, 2826, 2834, 2826, 2832, 2827, 2838, 2828, 2828, - 2829, 2842, 2834, 2836, 2835, 2839, 2840, 2831, 2831, 2833, - 2841, 2846, 2837, 2835, 2833, 0, 2836, 2837, 2839, 2840, - 2834, 2845, 2838, 2842, 2838, 2841, 2848, 2843, 2842, 2844, - 2847, 2849, 2839, 2840, 2843, 2850, 2844, 2841, 2846, 2852, - 2851, 2853, 2847, 2845, 2855, 0, 2856, 2854, 2845, 2857, - 2853, 0, 2859, 2848, 2843, 2851, 2844, 2847, 2849, 2859, - 0, 2864, 2850, 2858, 2852, 2860, 2852, 2851, 2853, 2854, - - 2855, 2855, 2856, 2856, 2854, 2857, 2857, 2861, 2858, 2859, - 2860, 2862, 2863, 2865, 2861, 2866, 2867, 2862, 2864, 2868, - 2858, 2865, 2860, 2863, 2869, 2871, 2870, 2874, 0, 2872, - 2873, 0, 2877, 2879, 2861, 2868, 0, 2873, 2862, 2863, - 2865, 2870, 2866, 2867, 2872, 2871, 2868, 0, 2875, 2874, - 2878, 2869, 2871, 2870, 2874, 2875, 2872, 2873, 2876, 2877, - 2879, 2880, 2880, 2881, 2882, 2876, 2883, 2884, 2878, 2883, - 2881, 2885, 2886, 0, 2887, 2875, 2890, 2878, 2882, 2887, - 2884, 2888, 2889, 2892, 2893, 2876, 2891, 2886, 2880, 2885, - 2881, 2882, 2899, 2883, 2884, 2892, 2893, 2889, 2885, 2886, - - 2898, 2887, 2890, 2890, 2891, 2895, 2888, 2896, 2888, 2889, - 2892, 2893, 2896, 2891, 2895, 2897, 2901, 2900, 2902, 2899, - 2897, 2900, 2898, 2905, 2903, 2904, 2906, 2898, 2908, 0, - 2912, 2902, 2895, 2907, 2896, 2914, 0, 0, 0, 0, - 2901, 2934, 2897, 2901, 2900, 2902, 2903, 2904, 2907, 2915, - 2905, 2903, 2904, 2906, 2908, 2908, 2912, 2912, 2915, 2916, - 2907, 2914, 2914, 2917, 2925, 2918, 2920, 2922, 2934, 2921, - 2935, 2917, 2922, 2920, 2923, 2916, 2915, 2918, 2921, 2927, - 2924, 2923, 2925, 2935, 2931, 0, 2916, 2924, 2926, 2933, - 2917, 2925, 2918, 2920, 2922, 2926, 2921, 2935, 2928, 2929, - - 2930, 2923, 2937, 2938, 2927, 2928, 2927, 2924, 2929, 2930, - 2931, 2931, 2933, 2936, 2940, 2926, 2933, 2941, 2936, 2942, - 2937, 0, 2943, 2945, 2944, 2928, 2929, 2930, 2942, 2937, - 2938, 2943, 2940, 2944, 2951, 2946, 2947, 2954, 2953, 2948, - 2936, 2940, 2949, 2945, 2941, 2947, 2942, 2946, 2948, 2943, - 2945, 2944, 2950, 2949, 2952, 2955, 2960, 2951, 2953, 2957, - 2950, 2951, 2946, 2947, 2954, 2953, 2948, 2956, 2957, 2949, - 2958, 2961, 2962, 0, 2956, 2963, 2964, 2952, 2965, 2950, - 2966, 2952, 2955, 2960, 2963, 2964, 2957, 2967, 2966, 2968, - 2965, 2958, 2969, 2973, 2956, 0, 2974, 2958, 2961, 2970, - - 2967, 2971, 2963, 2964, 2962, 2965, 2970, 2966, 2971, 2973, - 2972, 2968, 2974, 2976, 2967, 2975, 2968, 2972, 2977, 2969, - 2973, 2978, 2975, 2974, 2979, 2980, 2970, 2983, 2971, 2985, - 2982, 2986, 0, 2989, 2988, 2976, 2990, 2972, 2982, 2986, - 2976, 2988, 2975, 2977, 2987, 2977, 2991, 2985, 2978, 2979, - 2992, 2979, 2980, 2991, 2983, 2989, 2985, 2982, 2986, 2987, - 2989, 2988, 2993, 2990, 2999, 3000, 2994, 2998, 2997, 2993, - 3001, 2987, 2992, 2991, 2994, 2997, 2998, 2992, 3002, 3003, - 3004, 3006, 3001, 3012, 0, 3018, 3005, 3002, 2999, 2993, - 3008, 2999, 3000, 2994, 2998, 2997, 3004, 3001, 3005, 3009, - - 3010, 3011, 3008, 0, 3006, 3002, 3003, 3004, 3006, 3013, - 3012, 3009, 3018, 3005, 3020, 3015, 3016, 3008, 3019, 3017, - 3021, 3010, 3020, 3013, 3011, 3019, 3009, 3010, 3011, 3015, - 3016, 3017, 3023, 3022, 3025, 3026, 3013, 3028, 3029, 3021, - 3022, 3020, 3015, 3016, 3027, 3019, 3017, 3021, 3030, 3025, - 3031, 3032, 3033, 3026, 3035, 3034, 3030, 3037, 0, 3023, - 3022, 3025, 3026, 3028, 3028, 3029, 3034, 3027, 3039, 3035, - 3033, 3027, 3043, 3032, 3039, 3030, 3036, 3031, 3032, 3033, - 3045, 3035, 3034, 3036, 3037, 3045, 3044, 3046, 3047, 3053, - 3050, 3048, 3049, 3051, 3052, 3039, 3057, 3055, 3043, 3043, - - 0, 0, 3047, 3036, 3044, 3048, 3049, 3045, 3050, 3055, - 3060, 3051, 3052, 3044, 3046, 3047, 3053, 3050, 3048, 3049, - 3051, 3052, 3054, 3057, 3055, 3062, 3063, 3065, 3064, 3054, - 3066, 3070, 3060, 3067, 3072, 0, 0, 3060, 3066, 3063, - 3068, 3073, 3075, 3070, 3076, 0, 3065, 3062, 3077, 3054, - 3064, 3067, 3062, 3063, 3065, 3064, 3072, 3066, 3070, 3068, - 3067, 3072, 3074, 3073, 3078, 3079, 3081, 3068, 3073, 3075, - 3077, 3076, 3080, 3083, 3074, 3077, 3078, 3082, 3086, 3084, - 3080, 3085, 0, 0, 3094, 3087, 0, 3079, 3084, 3074, - 3085, 3078, 3079, 3081, 3088, 3083, 3089, 3082, 3091, 3080, - - 3083, 3092, 3095, 3099, 3082, 3093, 3084, 3087, 3085, 3089, - 3086, 3094, 3087, 3092, 3098, 3100, 3088, 3099, 3103, 3101, - 3105, 3088, 3104, 3089, 3091, 3091, 3102, 3093, 3092, 3095, - 3099, 3102, 3093, 3105, 3106, 3108, 3098, 3107, 3110, 3114, - 3103, 3098, 3100, 3101, 3104, 3103, 3101, 3105, 3109, 3104, - 3112, 3111, 3115, 3113, 3116, 0, 3110, 3108, 3102, 3113, - 3107, 3118, 3108, 3111, 3107, 3110, 3106, 3117, 3121, 3112, - 3109, 3114, 3120, 3122, 3124, 3109, 3116, 3112, 3111, 3130, - 3113, 3116, 3117, 3126, 3115, 3127, 3128, 3129, 3118, 3124, - 3121, 3131, 3120, 3130, 3117, 3121, 3129, 3122, 3132, 3120, - - 3122, 3124, 3133, 3134, 3135, 3126, 3130, 3127, 3128, 3131, - 3126, 3136, 3127, 3128, 3129, 3137, 3132, 3140, 3131, 3141, - 3142, 3134, 3149, 0, 0, 3132, 3140, 3135, 3133, 3133, - 3134, 3135, 3145, 3150, 3153, 0, 3154, 3137, 3146, 3147, - 3145, 3142, 3137, 3136, 3140, 3146, 3147, 3142, 3148, 3149, - 3151, 3141, 3153, 3150, 3154, 3155, 3148, 3156, 3151, 3145, - 3150, 3153, 3157, 3154, 3158, 3146, 3147, 3159, 3167, 3156, - 3160, 3162, 3164, 3166, 3169, 3148, 3158, 3151, 3160, 3164, - 3157, 3155, 3155, 3162, 3156, 3168, 3170, 3168, 3175, 3157, - 3174, 3158, 3178, 3172, 3159, 3167, 3166, 3160, 3162, 3164, - - 3166, 3172, 3173, 3177, 3176, 3177, 3169, 3180, 3183, 3184, - 3181, 3173, 3168, 0, 3178, 3175, 3185, 3186, 3170, 3178, - 3172, 3188, 3174, 3176, 3181, 3180, 3186, 3191, 3187, 3173, - 3177, 3176, 3196, 3184, 3180, 3189, 3184, 3181, 3192, 3185, - 3183, 3187, 3193, 3185, 3186, 3198, 3197, 3189, 3188, 3194, - 3197, 3199, 3201, 3191, 3191, 3187, 0, 3202, 3194, 3196, - 3192, 3203, 3189, 3204, 3193, 3192, 3206, 3208, 3214, 3193, - 3209, 3210, 3198, 3197, 3208, 3214, 3194, 3211, 3199, 3201, - 3202, 3204, 3211, 3203, 3202, 3212, 3210, 3217, 3203, 3215, - 3204, 3219, 3209, 3206, 3208, 3214, 3215, 3209, 3210, 3216, - - 3212, 3220, 3221, 3222, 3226, 3223, 3216, 3224, 3227, 3211, - 3230, 3232, 3212, 3217, 3217, 3229, 3215, 3227, 3219, 3223, - 3231, 3224, 3229, 3234, 3233, 3235, 3216, 3222, 3220, 3221, - 3222, 3226, 3223, 3238, 3224, 3227, 3233, 3230, 3232, 3235, - 3236, 3237, 3229, 3239, 3245, 3244, 3231, 3231, 3240, 3236, - 3234, 3233, 3235, 3243, 3237, 3246, 3248, 3250, 3243, 3249, - 3252, 3248, 3253, 3249, 3250, 3238, 3251, 3236, 3237, 3244, - 3239, 3240, 3244, 3251, 3254, 3240, 3245, 3246, 3255, 0, - 3257, 3252, 3246, 3361, 3250, 3243, 3249, 3252, 3248, 3256, - 3258, 3256, 3261, 3251, 3253, 3264, 3262, 3265, 3267, 0, - - 3267, 3269, 3268, 3257, 0, 0, 3254, 3257, 3273, 0, - 3255, 3271, 3276, 0, 3264, 3361, 3256, 3258, 3262, 3261, - 0, 3265, 3264, 3262, 3265, 3267, 3268, 3269, 3269, 3268, - 3270, 3270, 3272, 3271, 3275, 3273, 3274, 3277, 3271, 3276, - 3270, 3272, 3279, 3274, 3278, 3280, 3281, 3275, 3286, 3283, - 3277, 3284, 3278, 3280, 3283, 3279, 3284, 3270, 3270, 3272, - 3287, 3275, 3285, 3274, 3277, 3281, 3288, 3296, 3278, 3279, - 3285, 3278, 3280, 3281, 3289, 3286, 3290, 0, 3291, 3278, - 3292, 3283, 0, 3284, 3293, 3296, 3287, 3287, 3294, 3285, - 3297, 3292, 3288, 3288, 3296, 3294, 3295, 3295, 3299, 3298, - - 3289, 3289, 3290, 3290, 3291, 3291, 3293, 3292, 3300, 3301, - 3297, 3293, 3298, 3307, 3302, 3294, 3300, 3297, 3308, 3309, - 3299, 3303, 3304, 3295, 3311, 3299, 3298, 3305, 3303, 3304, - 3310, 3301, 3302, 3313, 3305, 3300, 3301, 3312, 3314, 3316, - 3307, 3302, 3310, 3309, 3318, 3308, 3309, 3314, 3303, 3304, - 3317, 3311, 3319, 3321, 3305, 3313, 3324, 3310, 3312, 0, - 3313, 3329, 3330, 3322, 3312, 3314, 3316, 3323, 3325, 3326, - 3317, 3318, 0, 3328, 3319, 3331, 3333, 3317, 0, 3319, - 3321, 3322, 3328, 3324, 3333, 3323, 3325, 3326, 3329, 3330, - 3322, 3332, 3334, 3335, 3323, 3325, 3326, 3336, 3331, 3339, - - 3328, 3337, 3331, 3333, 3336, 3335, 3337, 3340, 3334, 3332, - 3341, 3342, 3343, 3339, 3349, 3345, 3350, 3351, 3332, 3334, - 3335, 3353, 3341, 3342, 3336, 3340, 3339, 3345, 3358, 3355, - 3351, 3355, 3354, 3337, 3340, 3343, 3349, 3341, 3342, 3343, - 3356, 3349, 3345, 3350, 3351, 3354, 3359, 3360, 3353, 3356, - 3366, 3362, 3366, 3367, 3368, 3358, 3355, 3370, 3371, 3354, - 3377, 3373, 3375, 0, 3370, 3360, 3362, 3356, 3375, 3378, - 0, 3379, 3368, 3359, 3360, 3367, 3373, 3366, 3362, 3383, - 3367, 3368, 3377, 3380, 3370, 3382, 3385, 3377, 3373, 3375, - 3371, 3378, 3383, 3390, 3386, 3391, 3378, 3379, 3379, 3392, - - 3393, 3380, 3385, 3387, 0, 0, 3383, 3382, 3386, 0, - 3380, 3388, 3382, 3385, 3388, 3396, 3387, 3394, 3393, 3404, - 3390, 3386, 3391, 3396, 3394, 3395, 3392, 3393, 3397, 3398, - 3387, 3401, 3395, 3406, 0, 3402, 3397, 3388, 3388, 3403, - 3405, 3388, 3396, 3408, 3394, 3409, 3404, 3407, 3406, 3405, - 3410, 3398, 3395, 3407, 3409, 3397, 3398, 3402, 3413, 3416, - 3406, 3403, 3402, 3401, 3415, 3408, 3403, 3405, 3417, 3412, - 3408, 3412, 3409, 3418, 3407, 3419, 3420, 3421, 3425, 3427, - 3470, 3416, 3410, 3419, 3428, 3413, 3416, 3415, 3420, 3421, - 3417, 3415, 3430, 3427, 3423, 3417, 3412, 3434, 3428, 3418, - - 3418, 3423, 3419, 3420, 3421, 3425, 3427, 3431, 3429, 3432, - 3433, 3428, 3470, 3437, 3440, 3430, 3434, 3435, 3433, 3430, - 3432, 3423, 3429, 3436, 3434, 3431, 3438, 3443, 3437, 3439, - 3436, 3444, 3440, 3438, 3431, 3429, 3432, 3433, 3441, 3435, - 3437, 3440, 3442, 3442, 3435, 3451, 3448, 3441, 3449, 3445, - 3436, 3448, 3452, 3438, 3443, 3439, 3439, 3445, 3444, 3453, - 3457, 3449, 3455, 3459, 3467, 3441, 3451, 3472, 3455, 3442, - 3460, 3462, 3451, 3463, 3459, 3449, 3445, 3464, 3448, 3452, - 3473, 3460, 3475, 3469, 3463, 3468, 3453, 3457, 3473, 3455, - 3459, 3467, 3468, 3462, 3472, 3483, 3481, 3460, 3462, 3464, - - 3463, 3469, 3471, 3476, 3464, 3477, 3471, 3473, 3475, 3475, - 3469, 3477, 3468, 3478, 3479, 3480, 3476, 3486, 3485, 3478, - 3492, 3487, 3479, 3481, 3480, 3485, 3490, 3483, 3493, 3471, - 3476, 3490, 3477, 3491, 3491, 3496, 3497, 3495, 3494, 3498, - 3478, 3479, 3480, 3487, 3495, 3485, 3502, 3492, 3487, 3486, - 3494, 3499, 3497, 3490, 3496, 3493, 3500, 3498, 3499, 3501, - 3491, 3502, 3496, 3497, 3495, 3494, 3498, 3501, 3503, 3504, - 3505, 3506, 3507, 3502, 0, 3503, 3508, 3509, 3499, 3510, - 0, 3496, 3515, 3516, 3507, 3517, 3501, 3514, 3500, 3515, - 3516, 3518, 3505, 3519, 3520, 3503, 3504, 3505, 3506, 3507, - - 3508, 3509, 3514, 3508, 3509, 3510, 3510, 3517, 3521, 3515, - 3516, 3524, 3517, 3528, 3514, 3522, 3525, 3526, 3520, 3527, - 3519, 3520, 3530, 3518, 3522, 3529, 3529, 3527, 3533, 3534, - 3536, 3534, 3532, 3524, 3535, 3529, 3539, 3533, 3524, 3526, - 3521, 3541, 3522, 3525, 3526, 3528, 3527, 3532, 3535, 3530, - 3537, 3538, 3529, 3529, 3539, 3533, 3534, 3536, 3537, 3532, - 3542, 3535, 3538, 3539, 3543, 0, 3544, 3545, 3541, 3547, - 3546, 3548, 3549, 3555, 3552, 3551, 3553, 3537, 3538, 3559, - 3545, 3551, 3550, 3554, 3554, 3556, 3562, 3542, 3544, 3563, - 3553, 3543, 3546, 3544, 3545, 0, 3547, 3546, 3548, 3549, - - 3550, 3552, 3551, 3553, 3560, 3555, 3559, 3556, 3572, 3550, - 3554, 3566, 3556, 3562, 3574, 3560, 3563, 3568, 3569, 3566, - 3570, 3571, 3568, 3569, 3575, 3575, 3571, 3577, 3570, 3576, - 3581, 3560, 3579, 3588, 3572, 3572, 3582, 3576, 3566, 3579, - 3577, 3574, 3580, 3582, 3568, 3569, 3583, 3570, 3571, 3584, - 3590, 3575, 3585, 3583, 3577, 3587, 3576, 3581, 3590, 3579, - 3580, 3589, 3591, 3582, 3587, 3588, 3595, 3596, 3589, 3580, - 3592, 3598, 3595, 3583, 3599, 3585, 3584, 3590, 3600, 3585, - 3601, 3603, 3587, 3604, 3591, 0, 3609, 3602, 3589, 3591, - 0, 3600, 3592, 3595, 3596, 3605, 3599, 3592, 3598, 3607, - - 3603, 3599, 3602, 3610, 3611, 3600, 3607, 3613, 3603, 3609, - 3604, 3611, 3601, 3609, 3602, 3616, 3612, 3605, 3614, 3617, - 3615, 0, 3605, 3612, 3616, 3610, 3607, 3625, 3620, 3613, - 3610, 3611, 3619, 3614, 3613, 3615, 3620, 3621, 3625, 3628, - 3617, 3622, 3616, 3612, 3621, 3614, 3617, 3615, 3622, 3624, - 3627, 3619, 3626, 3626, 3625, 3620, 3627, 3632, 3624, 3619, - 3630, 3628, 3626, 3631, 3621, 3635, 3628, 3637, 3622, 3633, - 3631, 3636, 3635, 3641, 3642, 3650, 3624, 3627, 3653, 3626, - 3626, 3637, 3630, 3643, 3658, 3647, 3648, 3630, 0, 3632, - 3631, 3633, 3635, 3651, 3637, 3636, 3633, 3647, 3636, 3652, - - 3641, 3642, 3650, 3661, 3655, 3653, 3643, 3652, 3648, 3663, - 3643, 3658, 3647, 3648, 3667, 3651, 3655, 3659, 3659, 0, - 3651, 3660, 3660, 3662, 3662, 0, 3652, 3665, 3668, 3666, - 3661, 3655, 3663, 3671, 3672, 3669, 3663, 3668, 3674, 0, - 3675, 3667, 3679, 0, 3676, 0, 3659, 3666, 3669, 3665, - 3660, 3676, 3662, 3678, 3665, 3668, 3666, 3677, 3685, 3680, - 3671, 3672, 3669, 3681, 3677, 3674, 3675, 3675, 3680, 3679, - 3681, 3676, 3684, 3686, 3684, 3678, 3687, 3688, 3685, 3690, - 3678, 3693, 3691, 3692, 3677, 3685, 3680, 3695, 3690, 3688, - 3681, 3696, 3697, 3694, 3687, 3698, 3686, 3699, 3704, 3684, - - 3686, 3701, 3699, 3687, 3688, 3692, 3690, 3691, 3693, 3691, - 3692, 3694, 3708, 3695, 3695, 3700, 3703, 0, 3696, 3697, - 3694, 3703, 3698, 3701, 3699, 3706, 3702, 3700, 3701, 3702, - 3704, 3705, 3707, 3705, 3708, 3709, 3711, 3706, 3707, 3708, - 3712, 3710, 3700, 3713, 3702, 0, 3714, 3715, 3703, 3710, - 0, 3720, 3706, 3702, 3716, 3717, 3702, 3709, 3705, 3707, - 3722, 3724, 3709, 3711, 3713, 3725, 3716, 3721, 3710, 3729, - 3713, 3730, 3712, 3714, 3715, 3727, 3731, 3717, 3720, 3732, - 3721, 3716, 3717, 3725, 3727, 3734, 3735, 3722, 3724, 3736, - 3737, 3740, 3725, 3741, 3721, 3745, 3729, 3746, 3730, 3738, - - 3738, 3748, 3727, 3731, 3747, 3751, 3732, 3753, 3748, 3740, - 0, 3750, 3734, 3735, 0, 3746, 3736, 3737, 3740, 3747, - 3741, 3752, 3745, 3750, 3746, 3754, 3738, 3755, 3748, 3752, - 3756, 3747, 3751, 3757, 3753, 3758, 3759, 3754, 3750, 3761, - 3762, 3755, 3766, 0, 3767, 3756, 3768, 3774, 3752, 3770, - 3758, 3761, 3754, 3767, 3755, 3769, 3769, 3756, 0, 3757, - 3757, 3773, 3758, 3759, 3766, 3771, 3761, 3762, 3775, 3766, - 3768, 3767, 3776, 3768, 3771, 3770, 3770, 0, 3777, 3774, - 3778, 3775, 3769, 3781, 3782, 3773, 3777, 3779, 3773, 3778, - 3785, 3786, 3771, 3788, 3776, 3775, 3791, 3791, 3779, 3776, - - 3801, 3792, 3782, 3786, 3781, 3777, 3802, 3778, 3792, 3806, - 3781, 3782, 3805, 3785, 3779, 3807, 3808, 3785, 3786, 3788, - 3788, 3810, 3801, 3791, 3814, 3812, 3805, 3801, 3792, 3812, - 3802, 3813, 3816, 3802, 3815, 3820, 3806, 3818, 3822, 3805, - 0, 3815, 3807, 3808, 3816, 3824, 3823, 3814, 3810, 3813, - 3818, 3814, 3812, 3821, 3822, 3826, 0, 3821, 3813, 3816, - 3829, 3815, 3825, 3827, 3818, 3822, 3833, 3820, 3823, 3829, - 3824, 3828, 3824, 3823, 3825, 3830, 3831, 3827, 3831, 3828, - 3821, 3826, 3826, 3832, 3833, 3834, 3830, 3829, 3836, 3825, - 3827, 3835, 3837, 3833, 3836, 3832, 3839, 3840, 3828, 3838, - - 3834, 3841, 3830, 3831, 3839, 3842, 3849, 3837, 3841, 3847, - 3832, 3850, 3834, 3835, 3852, 3836, 3851, 3853, 3835, 3837, - 3854, 3838, 3847, 3839, 3840, 3855, 3838, 3842, 3841, 3850, - 3848, 3856, 3842, 3849, 3857, 3859, 3847, 3848, 3850, 3853, - 3851, 3852, 3857, 3851, 3853, 3860, 3854, 3854, 3858, 3861, - 3864, 3862, 3855, 3862, 3863, 3858, 3865, 3848, 3856, 3859, - 3868, 3857, 3859, 3867, 3866, 3870, 3863, 3860, 3871, 3865, - 3869, 3861, 3860, 3872, 3874, 3858, 3861, 3869, 3862, 3866, - 3876, 3863, 3864, 3865, 3875, 3867, 3877, 3868, 3876, 3883, - 3867, 3866, 3870, 3879, 3880, 3871, 3875, 3869, 3883, 3882, - - 3872, 3874, 3882, 3886, 3888, 3879, 3887, 3876, 3890, 3889, - 3880, 3875, 3891, 3877, 3892, 3893, 3883, 3889, 3896, 0, - 3879, 3880, 3898, 3888, 3895, 3906, 3882, 3892, 3903, 3893, - 3886, 3888, 3887, 3887, 3903, 3894, 3889, 3907, 3906, 3908, - 3890, 3892, 3893, 3894, 3891, 3896, 3895, 3904, 3909, 3898, - 3908, 3895, 3906, 3911, 3904, 3903, 3912, 3913, 3914, 3915, - 3911, 3916, 3894, 0, 3907, 3913, 3908, 3917, 3918, 3916, - 3919, 3909, 3914, 3915, 3904, 3909, 3927, 3929, 3912, 3928, - 3911, 3926, 0, 3912, 3913, 3914, 3915, 3923, 3916, 3917, - 3918, 3922, 3924, 3931, 3917, 3918, 3923, 3919, 3922, 3926, - - 3924, 3928, 3930, 3927, 3932, 3933, 3928, 3935, 3926, 3929, - 3937, 3938, 0, 3934, 3923, 3931, 3939, 0, 3922, 3924, - 3931, 3934, 3942, 0, 3947, 3940, 3932, 3933, 3930, 3930, - 3944, 3932, 3933, 3938, 3940, 0, 3943, 3937, 3938, 3935, - 3934, 3951, 3953, 3939, 3943, 3942, 3945, 3946, 3949, 3942, - 3944, 3948, 3940, 3954, 3945, 3946, 3947, 3944, 3955, 3948, - 3956, 3955, 3949, 3943, 3953, 3960, 0, 3951, 3951, 3953, - 3959, 3957, 3961, 3945, 3946, 3949, 3955, 3966, 3948, 3957, - 3954, 3958, 3956, 3963, 3959, 3955, 3962, 3956, 3955, 3958, - 3968, 3960, 3960, 3967, 3961, 3965, 3965, 3959, 3957, 3961, - - 3962, 3967, 3969, 3966, 3966, 3970, 3963, 3972, 3958, 3973, - 3963, 3971, 3974, 3962, 3977, 3972, 3968, 3968, 3975, 3976, - 3967, 0, 3965, 3978, 3985, 0, 0, 3970, 3969, 3969, - 3981, 3971, 3970, 3979, 3972, 0, 3973, 3988, 3971, 3974, - 3975, 3977, 0, 3978, 3976, 3975, 3976, 3980, 3982, 3989, - 3978, 3985, 3981, 3979, 3986, 3980, 3982, 3981, 3990, 3988, - 3979, 3991, 3986, 3992, 3988, 3994, 3990, 3997, 3998, 3991, - 3995, 3989, 3996, 4001, 3980, 3982, 3989, 4002, 3995, 4005, - 3996, 3986, 3999, 4003, 0, 3990, 4008, 4011, 3991, 3992, - 3992, 4012, 3994, 3997, 3997, 3998, 0, 3995, 0, 3996, - - 4001, 4005, 3999, 4003, 4002, 0, 4005, 4009, 4008, 3999, - 4003, 4010, 0, 4008, 4011, 4009, 0, 0, 4012, 4010, - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 4009, 0, 0, 0, 4010, 4016, - 4016, 4016, 4016, 4016, 4016, 4016, 4017, 4017, 4017, 4017, - 4017, 4017, 4017, 4018, 4018, 4018, 4018, 4018, 4018, 4018, - 4019, 4019, 4019, 4019, 4019, 4019, 4019, 4020, 4020, 4020, - 4020, 4020, 4020, 4020, 4021, 4021, 4021, 4021, 4021, 4021, - 4021, 4022, 4022, 4022, 4022, 4022, 4022, 4022, 4024, 4024, - 0, 4024, 4024, 4024, 4024, 4025, 4025, 0, 0, 0, - - 4025, 4025, 4026, 4026, 0, 0, 4026, 0, 4026, 4027, - 0, 0, 0, 0, 0, 4027, 4028, 4028, 0, 0, - 0, 4028, 4028, 4029, 0, 0, 0, 0, 0, 4029, - 4030, 4030, 0, 4030, 4030, 4030, 4030, 4031, 0, 0, - 0, 0, 0, 4031, 4032, 4032, 0, 0, 0, 4032, - 4032, 4033, 4033, 0, 4033, 4033, 4033, 4033, 4015, 4015, - 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, - 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, - 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, - 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, - - 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, - 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, 4015, - 4015, 4015, 4015, 4015, 4015 + 294, 296, 307, 310, 295, 301, 296, 300, 302, 298, + + 297, 304, 299, 304, 301, 303, 308, 312, 305, 309, + 323, 306, 302, 303, 306, 310, 312, 307, 313, 307, + 310, 314, 317, 0, 316, 0, 315, 325, 304, 318, + 0, 327, 308, 308, 312, 309, 309, 315, 316, 319, + 320, 331, 323, 329, 313, 313, 317, 314, 314, 317, + 316, 316, 318, 315, 321, 324, 318, 319, 320, 325, + 326, 328, 321, 327, 330, 316, 319, 320, 324, 329, + 329, 332, 333, 331, 334, 336, 0, 0, 328, 333, + 337, 321, 324, 334, 328, 326, 330, 326, 328, 336, + 335, 330, 338, 346, 0, 332, 335, 340, 0, 333, + + 339, 334, 336, 332, 341, 328, 337, 337, 343, 339, + 0, 347, 341, 348, 342, 345, 338, 335, 377, 338, + 340, 344, 332, 342, 340, 346, 347, 339, 349, 350, + 344, 341, 345, 0, 343, 343, 352, 353, 347, 345, + 354, 342, 345, 357, 350, 348, 353, 0, 344, 382, + 377, 358, 349, 356, 352, 349, 350, 357, 362, 345, + 351, 363, 354, 352, 353, 351, 358, 354, 351, 0, + 357, 359, 359, 351, 351, 351, 351, 356, 358, 360, + 356, 382, 362, 351, 360, 362, 0, 351, 363, 370, + 0, 0, 351, 0, 368, 351, 359, 365, 359, 359, + + 351, 351, 351, 351, 355, 369, 355, 364, 355, 365, + 364, 360, 368, 366, 0, 372, 370, 364, 355, 355, + 355, 368, 355, 369, 365, 366, 367, 367, 355, 371, + 376, 355, 369, 355, 364, 355, 367, 364, 373, 0, + 366, 372, 372, 375, 378, 355, 355, 355, 374, 355, + 374, 371, 376, 367, 367, 375, 371, 376, 379, 378, + 380, 381, 385, 387, 373, 373, 379, 380, 0, 385, + 375, 378, 383, 381, 383, 374, 394, 0, 386, 0, + 388, 0, 390, 383, 390, 379, 389, 380, 381, 385, + 383, 391, 389, 392, 394, 387, 395, 396, 383, 383, + + 386, 383, 388, 394, 391, 386, 390, 388, 389, 390, + 383, 390, 397, 389, 393, 398, 402, 383, 391, 389, + 405, 401, 395, 395, 403, 392, 412, 393, 401, 396, + 393, 412, 393, 405, 402, 0, 403, 398, 393, 397, + 402, 393, 398, 402, 404, 0, 413, 405, 401, 407, + 0, 403, 0, 0, 393, 410, 404, 393, 412, 393, + 399, 402, 399, 411, 0, 407, 408, 410, 399, 415, + 0, 404, 399, 407, 421, 415, 407, 399, 413, 408, + 399, 411, 410, 421, 414, 417, 399, 399, 418, 399, + 411, 414, 407, 408, 416, 399, 415, 417, 470, 399, + + 420, 421, 416, 0, 399, 414, 418, 399, 400, 419, + 400, 414, 417, 422, 422, 418, 424, 419, 414, 470, + 423, 416, 433, 400, 425, 470, 400, 423, 400, 424, + 400, 440, 420, 425, 400, 400, 419, 400, 427, 428, + 422, 0, 0, 424, 0, 427, 428, 423, 0, 429, + 400, 430, 431, 400, 433, 400, 425, 400, 409, 409, + 425, 429, 426, 440, 434, 427, 428, 0, 409, 409, + 409, 409, 409, 430, 431, 409, 429, 436, 430, 431, + 426, 432, 0, 409, 426, 409, 409, 435, 438, 426, + 434, 434, 436, 432, 435, 409, 409, 409, 409, 409, + + 437, 438, 409, 439, 436, 442, 443, 426, 432, 437, + 447, 441, 439, 441, 435, 438, 442, 444, 444, 0, + 450, 447, 445, 448, 446, 453, 449, 437, 443, 445, + 439, 446, 442, 443, 448, 451, 0, 447, 441, 449, + 452, 452, 0, 0, 455, 450, 444, 450, 453, 445, + 448, 446, 453, 449, 454, 456, 0, 451, 452, 0, + 457, 0, 451, 456, 458, 452, 460, 452, 452, 454, + 455, 455, 457, 463, 459, 458, 464, 454, 468, 460, + 482, 454, 456, 459, 465, 452, 466, 457, 461, 461, + 467, 458, 469, 460, 464, 471, 454, 472, 469, 0, + + 461, 459, 461, 464, 473, 463, 465, 461, 467, 466, + 468, 465, 482, 466, 475, 461, 461, 467, 471, 469, + 476, 472, 471, 477, 472, 0, 473, 461, 474, 461, + 462, 473, 479, 484, 476, 474, 478, 480, 462, 462, + 475, 475, 462, 462, 478, 481, 462, 476, 0, 485, + 477, 480, 462, 483, 479, 474, 484, 462, 0, 479, + 484, 485, 486, 478, 480, 462, 462, 490, 486, 462, + 462, 481, 481, 462, 487, 483, 485, 488, 0, 489, + 483, 491, 490, 492, 496, 493, 0, 489, 491, 486, + 496, 494, 492, 499, 490, 497, 487, 498, 495, 488, + + 493, 487, 501, 503, 488, 489, 489, 504, 491, 503, + 492, 496, 493, 495, 489, 494, 499, 497, 494, 498, + 499, 500, 497, 502, 498, 495, 505, 507, 501, 501, + 503, 505, 0, 504, 504, 508, 500, 510, 511, 0, + 512, 514, 513, 510, 515, 502, 512, 514, 500, 516, + 502, 521, 0, 505, 522, 517, 516, 511, 521, 507, + 513, 508, 508, 524, 510, 511, 515, 512, 514, 513, + 517, 515, 519, 527, 519, 520, 516, 523, 521, 526, + 525, 519, 517, 525, 520, 529, 522, 528, 0, 530, + 523, 525, 530, 531, 535, 524, 0, 526, 529, 519, + + 532, 519, 520, 533, 523, 527, 526, 525, 530, 528, + 525, 534, 529, 532, 528, 533, 530, 531, 536, 530, + 531, 538, 537, 539, 543, 536, 535, 532, 541, 534, + 533, 542, 540, 541, 545, 547, 539, 542, 534, 570, + 0, 0, 544, 570, 538, 536, 537, 543, 546, 537, + 539, 543, 544, 538, 540, 541, 545, 547, 542, 540, + 546, 545, 547, 548, 549, 550, 570, 554, 555, 544, + 553, 538, 549, 554, 548, 546, 556, 553, 557, 550, + 555, 591, 558, 596, 0, 605, 557, 560, 0, 562, + 548, 549, 550, 551, 554, 555, 559, 553, 551, 556, + + 551, 562, 0, 556, 558, 557, 551, 559, 551, 558, + 560, 551, 551, 591, 560, 596, 562, 605, 551, 551, + 551, 563, 561, 559, 565, 551, 561, 551, 0, 564, + 569, 0, 564, 551, 567, 551, 0, 566, 551, 551, + 564, 563, 565, 563, 561, 551, 567, 566, 563, 561, + 572, 565, 568, 561, 569, 571, 564, 569, 573, 564, + 573, 567, 571, 568, 574, 576, 575, 579, 563, 566, + 578, 577, 0, 581, 566, 579, 572, 572, 575, 568, + 576, 580, 571, 577, 582, 573, 580, 588, 585, 584, + 574, 574, 576, 575, 579, 581, 578, 578, 577, 583, + + 581, 584, 582, 587, 589, 588, 590, 583, 580, 585, + 592, 582, 593, 594, 588, 585, 584, 0, 587, 595, + 599, 594, 597, 601, 593, 592, 583, 589, 600, 590, + 587, 589, 595, 590, 597, 598, 604, 592, 602, 593, + 594, 602, 600, 599, 598, 603, 595, 599, 601, 597, + 601, 606, 607, 608, 609, 600, 610, 0, 0, 612, + 611, 616, 598, 604, 603, 602, 606, 613, 614, 609, + 616, 612, 603, 611, 615, 621, 622, 0, 606, 624, + 610, 609, 618, 610, 607, 608, 612, 611, 616, 613, + 617, 614, 620, 618, 613, 614, 625, 617, 615, 619, + + 617, 615, 621, 622, 619, 626, 620, 627, 617, 618, + 628, 624, 0, 629, 630, 628, 633, 617, 631, 620, + 630, 634, 629, 625, 617, 632, 636, 617, 635, 634, + 641, 619, 626, 631, 637, 0, 639, 640, 633, 627, + 629, 630, 628, 633, 639, 631, 643, 635, 634, 632, + 636, 647, 632, 636, 638, 635, 637, 645, 638, 642, + 640, 637, 641, 639, 640, 644, 642, 646, 650, 643, + 648, 0, 654, 643, 644, 656, 652, 647, 647, 645, + 646, 638, 648, 649, 645, 651, 642, 652, 656, 649, + 650, 653, 644, 651, 646, 650, 659, 648, 653, 655, + + 657, 665, 656, 652, 654, 657, 658, 660, 657, 657, + 649, 0, 651, 665, 661, 658, 660, 662, 653, 668, + 663, 655, 659, 659, 657, 661, 655, 657, 665, 667, + 664, 669, 657, 658, 660, 657, 657, 670, 672, 662, + 671, 661, 663, 664, 662, 674, 672, 663, 673, 669, + 677, 668, 675, 667, 679, 676, 667, 664, 669, 677, + 678, 670, 671, 671, 670, 672, 676, 671, 679, 674, + 673, 680, 674, 682, 675, 673, 681, 677, 683, 675, + 678, 679, 676, 681, 684, 685, 686, 678, 687, 671, + 689, 688, 684, 680, 687, 691, 683, 685, 680, 692, + + 682, 689, 690, 681, 688, 683, 693, 704, 686, 0, + 691, 684, 685, 686, 694, 687, 697, 689, 688, 696, + 690, 0, 691, 695, 695, 0, 698, 693, 699, 690, + 696, 692, 700, 693, 701, 702, 703, 699, 694, 704, + 697, 694, 705, 697, 703, 700, 696, 701, 698, 706, + 707, 709, 695, 698, 0, 699, 708, 702, 708, 700, + 710, 701, 702, 703, 705, 711, 712, 713, 714, 705, + 711, 710, 717, 709, 707, 715, 0, 707, 709, 713, + 712, 706, 718, 708, 721, 726, 714, 710, 719, 715, + 718, 721, 741, 712, 713, 714, 722, 711, 0, 720, + + 0, 0, 715, 716, 717, 716, 719, 0, 723, 718, + 725, 721, 716, 724, 727, 719, 730, 726, 716, 716, + 716, 720, 722, 722, 741, 725, 720, 716, 723, 727, + 716, 729, 716, 724, 725, 723, 729, 725, 728, 716, + 724, 727, 730, 730, 732, 716, 716, 716, 728, 731, + 733, 731, 725, 734, 739, 735, 742, 736, 733, 737, + 728, 735, 739, 729, 738, 728, 736, 740, 737, 732, + 743, 732, 0, 738, 740, 728, 731, 733, 734, 742, + 734, 739, 735, 742, 736, 0, 737, 744, 743, 745, + 747, 738, 750, 746, 740, 748, 749, 743, 747, 744, + + 751, 745, 746, 754, 748, 752, 753, 751, 749, 755, + 0, 754, 757, 0, 744, 755, 745, 747, 752, 748, + 746, 753, 748, 749, 750, 789, 756, 751, 758, 759, + 754, 748, 752, 753, 756, 757, 755, 758, 760, 757, + 759, 761, 761, 762, 763, 764, 765, 760, 766, 768, + 761, 762, 763, 756, 767, 758, 759, 789, 769, 765, + 772, 0, 768, 770, 0, 760, 769, 764, 761, 761, + 762, 763, 764, 765, 766, 766, 768, 767, 771, 770, + 774, 767, 772, 773, 775, 769, 776, 772, 774, 778, + 770, 771, 777, 779, 773, 780, 779, 0, 775, 781, + + 784, 799, 785, 782, 783, 771, 776, 774, 868, 778, + 773, 775, 782, 776, 777, 785, 778, 780, 784, 777, + 779, 781, 780, 786, 783, 787, 781, 784, 799, 785, + 782, 783, 788, 790, 791, 868, 793, 0, 794, 792, + 796, 786, 795, 787, 797, 798, 806, 788, 801, 793, + 786, 798, 787, 801, 795, 790, 794, 797, 791, 788, + 790, 791, 792, 793, 796, 794, 792, 796, 800, 795, + 802, 797, 798, 803, 805, 807, 800, 808, 806, 811, + 801, 811, 805, 807, 808, 809, 813, 812, 814, 817, + 810, 803, 802, 0, 800, 800, 812, 802, 816, 844, + + 803, 805, 807, 800, 808, 810, 811, 815, 809, 817, + 816, 885, 809, 818, 812, 823, 817, 810, 813, 819, + 814, 819, 818, 820, 0, 816, 815, 823, 827, 830, + 820, 844, 831, 0, 815, 841, 833, 836, 827, 834, + 818, 833, 823, 885, 841, 887, 819, 830, 836, 0, + 820, 821, 835, 831, 821, 827, 830, 837, 821, 831, + 834, 821, 841, 833, 836, 838, 834, 839, 821, 821, + 835, 821, 887, 840, 842, 843, 821, 0, 821, 835, + 837, 821, 843, 846, 837, 821, 847, 842, 821, 840, + 846, 838, 838, 839, 839, 821, 821, 853, 821, 848, + + 840, 842, 843, 845, 845, 848, 845, 849, 847, 845, + 846, 0, 850, 847, 845, 851, 849, 854, 851, 853, + 845, 845, 852, 845, 853, 854, 848, 0, 856, 845, + 845, 845, 855, 845, 849, 850, 845, 858, 852, 850, + 856, 845, 851, 860, 854, 852, 861, 845, 845, 852, + 845, 857, 859, 857, 855, 856, 862, 859, 863, 855, + 864, 858, 870, 860, 858, 852, 865, 866, 862, 0, + 860, 871, 861, 861, 867, 869, 872, 870, 857, 871, + 863, 873, 0, 862, 859, 863, 864, 864, 865, 870, + 873, 866, 876, 865, 866, 877, 867, 874, 871, 872, + + 869, 867, 869, 872, 874, 875, 878, 879, 873, 881, + 880, 876, 883, 875, 879, 884, 882, 891, 878, 876, + 884, 877, 877, 880, 874, 882, 886, 883, 890, 892, + 896, 0, 875, 878, 879, 881, 881, 880, 893, 883, + 888, 897, 884, 882, 894, 888, 899, 893, 886, 891, + 890, 895, 894, 886, 892, 890, 892, 898, 895, 900, + 901, 902, 896, 897, 903, 893, 904, 908, 897, 0, + 899, 894, 888, 899, 906, 904, 905, 907, 895, 901, + 900, 911, 909, 906, 913, 916, 900, 901, 902, 898, + 908, 903, 911, 904, 908, 905, 910, 914, 912, 907, + + 915, 906, 909, 905, 907, 910, 912, 917, 911, 909, + 919, 913, 916, 918, 921, 914, 924, 922, 919, 915, + 923, 923, 918, 910, 914, 912, 922, 915, 926, 928, + 925, 926, 921, 927, 924, 930, 929, 919, 0, 917, + 918, 921, 925, 924, 922, 927, 931, 923, 933, 932, + 934, 928, 934, 930, 935, 926, 928, 925, 929, 939, + 927, 933, 930, 929, 936, 942, 938, 0, 940, 937, + 931, 932, 935, 931, 937, 933, 932, 934, 936, 938, + 940, 935, 941, 942, 943, 939, 939, 943, 944, 947, + 941, 936, 942, 938, 945, 940, 948, 944, 949, 951, + + 950, 937, 945, 953, 949, 951, 952, 0, 955, 941, + 953, 943, 954, 955, 947, 944, 947, 956, 945, 954, + 957, 945, 950, 948, 956, 949, 951, 950, 952, 945, + 953, 959, 958, 952, 960, 955, 958, 961, 957, 954, + 962, 964, 963, 960, 956, 961, 965, 957, 969, 967, + 968, 972, 970, 983, 959, 966, 964, 965, 959, 958, + 963, 960, 967, 966, 961, 970, 971, 969, 964, 963, + 0, 968, 962, 965, 975, 969, 967, 968, 972, 970, + 974, 973, 966, 976, 977, 983, 0, 974, 971, 973, + 976, 978, 975, 971, 979, 981, 980, 984, 978, 979, + + 985, 975, 981, 977, 980, 982, 986, 974, 973, 988, + 976, 977, 982, 985, 989, 987, 988, 990, 978, 0, + 991, 979, 981, 980, 995, 992, 993, 985, 987, 984, + 995, 999, 982, 992, 993, 994, 988, 996, 986, 997, + 998, 993, 987, 991, 1002, 0, 989, 991, 1004, 990, + 1000, 995, 992, 993, 1001, 999, 1005, 994, 999, 1000, + 1003, 993, 994, 996, 996, 1005, 1006, 1003, 1001, 1007, + 1056, 997, 998, 1008, 1009, 1004, 1002, 1000, 1010, 1009, + 1006, 1001, 1012, 1005, 1011, 1014, 1008, 1003, 1008, 1013, + 1010, 1007, 1014, 1006, 1013, 1016, 1007, 1008, 1015, 0, + + 1008, 1019, 1056, 0, 1019, 1010, 1009, 1011, 1012, 1012, + 1015, 1011, 1014, 1008, 1020, 1008, 1013, 1016, 1017, 1021, + 1023, 1029, 1016, 1025, 1024, 1015, 1017, 1020, 1019, 1025, + 1021, 1024, 1027, 0, 1023, 1028, 1031, 0, 0, 0, + 1030, 1020, 1057, 1021, 1029, 1017, 1021, 1023, 1029, 0, + 1025, 1024, 1030, 1032, 1027, 1032, 1036, 1021, 1026, 1027, + 1026, 1028, 1028, 1031, 1026, 1036, 1026, 1030, 1034, 1033, + 1033, 1026, 1035, 1037, 1057, 1034, 1026, 1039, 0, 1038, + 1032, 1049, 1026, 1036, 1035, 1026, 1037, 1026, 0, 1040, + 1039, 1026, 1033, 1026, 1040, 1034, 1033, 1033, 1026, 1035, + + 1037, 1038, 1041, 1026, 1039, 1042, 1038, 1043, 1049, 1045, + 1044, 1046, 0, 1045, 1048, 1051, 0, 1047, 1042, 1043, + 1041, 1040, 1044, 1045, 1060, 1050, 1046, 1048, 1051, 1041, + 1043, 1050, 1042, 1052, 1043, 1045, 1045, 1044, 1046, 1047, + 1045, 1048, 1051, 1053, 1047, 1054, 1043, 1055, 1058, 1061, + 1045, 1052, 1050, 1062, 1061, 1063, 1060, 1066, 1065, 0, + 1052, 1062, 1068, 0, 1063, 1053, 1054, 1069, 1067, 1055, + 1053, 0, 1054, 1065, 1055, 1058, 1061, 1068, 1070, 1066, + 1062, 1067, 1063, 1064, 1066, 1065, 1072, 1071, 1064, 1068, + 1064, 1074, 1073, 1069, 1069, 1067, 1064, 0, 1078, 1072, + + 1070, 1064, 1064, 1073, 1074, 1070, 1071, 1085, 1064, 1064, + 1064, 1077, 1075, 1072, 1071, 1064, 1076, 1064, 1074, 1073, + 1075, 1080, 1077, 1064, 1076, 1079, 1082, 1086, 1064, 1064, + 1078, 1081, 1083, 1084, 1085, 1064, 1080, 1082, 1077, 1075, + 1081, 1083, 1084, 1076, 1087, 1089, 1090, 1079, 1080, 1091, + 1086, 1087, 1079, 1082, 1086, 1093, 1092, 1091, 1081, 1083, + 1084, 1094, 1095, 1098, 1096, 1101, 0, 1099, 1100, 1093, + 1090, 1087, 1096, 1090, 1102, 0, 1091, 1089, 1092, 1100, + 1102, 1098, 1093, 1092, 1095, 1099, 1103, 1105, 1104, 1095, + 1098, 1096, 1106, 1094, 1099, 1100, 1104, 1101, 1107, 1106, + + 1108, 1102, 1110, 1109, 1103, 1111, 1112, 1113, 1114, 1105, + 1109, 1107, 1115, 1103, 1105, 1104, 1121, 1110, 1114, 1106, + 1117, 1124, 0, 1111, 1112, 1107, 1108, 1108, 1113, 1110, + 1109, 1117, 1111, 1112, 1113, 1114, 1119, 1122, 1120, 1122, + 1123, 1127, 1121, 1121, 1115, 1120, 1125, 1117, 1126, 1119, + 1127, 0, 1129, 1124, 1125, 1130, 1133, 1128, 1134, 1137, + 1136, 1126, 1123, 1119, 1122, 1120, 1138, 1123, 1127, 1128, + 1135, 0, 1139, 1125, 1129, 1126, 0, 1130, 1133, 1129, + 1134, 1140, 1130, 1133, 1128, 1134, 1136, 1136, 1135, 1141, + 1139, 1137, 1151, 1140, 1143, 1144, 1148, 1135, 1138, 1139, + + 1144, 1147, 1149, 1141, 1146, 1143, 0, 1146, 1140, 1160, + 1150, 1152, 0, 1147, 1151, 1149, 1141, 1150, 1152, 1151, + 1148, 1143, 1154, 1148, 1155, 1153, 1153, 1144, 1147, 1149, + 1146, 1146, 1156, 1154, 1146, 1159, 1157, 1150, 1152, 1153, + 1158, 1160, 1162, 1156, 1155, 1157, 1163, 1159, 1161, 1154, + 1164, 1155, 1153, 1153, 1158, 1161, 1165, 1168, 1163, 1156, + 1167, 0, 1159, 1157, 1169, 1172, 1170, 1158, 1171, 1165, + 1169, 1173, 1164, 1163, 1162, 1161, 1172, 1164, 1174, 1175, + 1183, 1168, 1176, 1165, 1168, 1179, 1167, 1167, 1170, 1173, + 1171, 1169, 1172, 1170, 1178, 1171, 1179, 1176, 1173, 1180, + + 1174, 1175, 1181, 1182, 1184, 1174, 1175, 1183, 1181, 1176, + 1185, 0, 1179, 1187, 1186, 1178, 1188, 1193, 1191, 1185, + 1180, 1178, 1184, 1190, 1189, 1188, 1180, 1194, 0, 1181, + 1190, 1184, 1189, 1192, 1195, 1182, 1196, 1185, 1186, 1187, + 1187, 1186, 1191, 1188, 1198, 1191, 1197, 1192, 1199, 1193, + 1190, 1189, 1200, 1203, 1204, 1202, 1205, 0, 1196, 1194, + 1192, 1204, 1203, 1196, 1206, 1207, 1195, 1208, 1197, 1209, + 1199, 1210, 1220, 1197, 1211, 1199, 1198, 1202, 1213, 1214, + 1203, 1204, 1202, 1211, 1200, 1208, 1206, 1209, 1205, 1212, + 1216, 1206, 1207, 1210, 1208, 1215, 1209, 1212, 1210, 1217, + + 1218, 1211, 1213, 1214, 1220, 1213, 1214, 1221, 1217, 1222, + 1219, 1215, 1216, 1223, 1224, 1218, 1212, 1216, 1219, 1226, + 1225, 1222, 1215, 1227, 1228, 1230, 1217, 1218, 1225, 1233, + 1231, 1233, 1226, 1228, 1230, 1223, 1222, 1219, 1227, 1221, + 1223, 1224, 1236, 1237, 1238, 1232, 1226, 1225, 1231, 0, + 1227, 1228, 1230, 1232, 1235, 1239, 1233, 1231, 1240, 1241, + 1236, 1243, 1235, 1238, 1244, 1246, 1241, 1248, 1245, 1236, + 1237, 1238, 1232, 1249, 1243, 1247, 1244, 1239, 1251, 1248, + 1240, 1235, 1239, 1245, 1253, 1240, 1241, 1246, 1243, 1250, + 1252, 1244, 1246, 1247, 1248, 1245, 1250, 1254, 1256, 1258, + + 1249, 1255, 1247, 1253, 1257, 1259, 1260, 0, 1261, 1254, + 1251, 1253, 1255, 1264, 1265, 1262, 1250, 0, 1259, 1260, + 1256, 1258, 1252, 1274, 1254, 1256, 1258, 1262, 1255, 1257, + 1261, 1257, 1259, 1260, 1265, 1261, 1263, 1264, 1266, 1267, + 1264, 1265, 1262, 1269, 1263, 1270, 1271, 1267, 1273, 1272, + 1266, 1283, 1275, 1276, 1277, 1274, 0, 1273, 1270, 0, + 1280, 1277, 1282, 1263, 1275, 1266, 1267, 1272, 1281, 1271, + 1269, 1285, 1270, 1271, 1276, 1273, 1272, 1278, 1283, 1275, + 1276, 1277, 1284, 1280, 1282, 1285, 1278, 1280, 1278, 1282, + 1286, 1278, 1287, 1288, 1281, 1281, 1289, 0, 1285, 1278, + + 1292, 1288, 1284, 1286, 1278, 1289, 1290, 1295, 1296, 1284, + 1294, 1301, 0, 1278, 0, 1278, 1287, 1286, 1278, 1287, + 1288, 1293, 1292, 1289, 1290, 1294, 1298, 1292, 1297, 1293, + 1296, 0, 1299, 1290, 1302, 1296, 1303, 1294, 1301, 1295, + 1299, 1297, 1298, 1304, 1305, 1306, 1307, 0, 1293, 0, + 1304, 0, 1310, 1298, 1321, 1297, 1302, 1308, 1303, 1299, + 1310, 1302, 1309, 1303, 1307, 1312, 1305, 1311, 1306, 1308, + 1304, 1305, 1306, 1307, 1309, 1313, 1311, 1312, 1314, 1310, + 1315, 1316, 0, 1318, 1308, 1319, 1321, 1316, 1315, 1309, + 1317, 1311, 1312, 1314, 1311, 1313, 0, 1319, 1320, 1317, + + 0, 1324, 1313, 1311, 1318, 1314, 1322, 1315, 1316, 1320, + 1318, 1323, 1319, 1322, 1320, 1325, 1326, 1317, 1323, 1324, + 1327, 1328, 1330, 1331, 1326, 1320, 1334, 1325, 1324, 1328, + 1329, 0, 1329, 1322, 1330, 1327, 1320, 1332, 1323, 1335, + 1336, 1337, 1325, 1326, 1332, 1338, 1344, 1327, 1328, 1330, + 1339, 1335, 1338, 1336, 1340, 1331, 1341, 1329, 1334, 1344, + 1337, 1339, 1351, 1348, 1332, 1342, 1335, 1336, 1337, 1346, + 1342, 1341, 1338, 1344, 1343, 1345, 1340, 1339, 1349, 0, + 0, 1340, 1343, 1341, 1356, 1354, 1350, 1353, 1348, 1345, + 1348, 1352, 1349, 1360, 1351, 1346, 1346, 1342, 0, 1360, + + 1357, 1343, 1345, 1347, 1350, 1349, 1355, 1347, 1354, 1353, + 1347, 1347, 1354, 1350, 1353, 1347, 1356, 1352, 1352, 1358, + 1360, 1347, 1357, 1359, 1355, 1347, 1364, 1357, 1361, 1347, + 1347, 0, 1363, 1355, 1347, 1364, 1361, 1347, 1347, 1363, + 0, 1358, 1347, 1362, 1366, 1362, 1358, 1365, 1347, 1359, + 1359, 1367, 1347, 1364, 1361, 1361, 1374, 1368, 1370, 1363, + 1369, 0, 1365, 1361, 1371, 1370, 1372, 1362, 1373, 1375, + 1362, 1376, 1362, 0, 1365, 1377, 1366, 1373, 1369, 1372, + 1379, 1368, 1378, 1367, 1368, 1370, 1371, 1369, 1374, 1381, + 1375, 1371, 0, 1372, 1379, 1373, 1375, 1377, 1383, 1382, + + 1384, 1384, 1377, 1376, 1385, 1378, 1388, 1379, 1392, 1378, + 1380, 1381, 1382, 1387, 0, 1380, 1381, 1380, 1388, 1380, + 1385, 1380, 1393, 1389, 1383, 1383, 1382, 1391, 1380, 1384, + 1389, 1385, 1390, 1388, 1394, 1392, 1387, 1380, 1395, 1394, + 1387, 1390, 1380, 1396, 1380, 1391, 1380, 1399, 1380, 1393, + 1389, 1397, 1395, 1398, 1391, 1400, 1396, 1401, 0, 1390, + 1400, 1407, 1399, 1402, 1404, 1395, 1394, 1403, 1409, 1397, + 1396, 1398, 1404, 1405, 1399, 1406, 1402, 1408, 1397, 1401, + 1398, 1405, 1400, 1409, 1401, 1403, 1410, 1415, 1406, 1412, + 1402, 1404, 1416, 1407, 1403, 1409, 1411, 1413, 1418, 1414, + + 1405, 1416, 1406, 1408, 1408, 1410, 1417, 1415, 1417, 1411, + 1413, 1412, 1419, 1410, 1415, 1420, 1412, 1414, 1421, 1416, + 1418, 1422, 1423, 1411, 1413, 1418, 1414, 1420, 1425, 1426, + 1427, 1429, 1428, 1417, 1430, 1431, 0, 1432, 1427, 1419, + 1434, 1430, 1420, 1422, 1433, 1421, 1434, 1423, 1422, 1423, + 1428, 1426, 1425, 1437, 1435, 1425, 1426, 1427, 1429, 1428, + 1435, 1430, 1431, 1432, 1432, 1438, 1433, 1434, 1436, 1439, + 1440, 1433, 1438, 1442, 1436, 1441, 1443, 1446, 0, 1439, + 1437, 1435, 1441, 1444, 1445, 0, 1446, 1449, 1448, 1454, + 0, 1451, 1438, 1450, 1440, 1436, 1439, 1440, 1443, 1449, + + 1453, 1444, 1441, 1443, 1446, 1442, 1452, 1450, 1454, 1445, + 1444, 1445, 1448, 1451, 1449, 1448, 1454, 1455, 1451, 1452, + 1450, 1456, 1453, 1458, 1457, 1459, 1460, 1453, 1465, 0, + 1466, 0, 0, 1452, 1461, 1460, 1462, 1467, 0, 1455, + 1463, 1469, 1473, 1468, 1455, 1456, 1457, 1459, 1456, 1458, + 1458, 1457, 1459, 1460, 1463, 1461, 1462, 1470, 1471, 1467, + 1465, 1461, 1466, 1462, 1467, 1468, 1471, 1463, 1477, 1473, + 1468, 1472, 1474, 1469, 1475, 1470, 1479, 1478, 1483, 1474, + 1480, 1475, 1481, 1484, 1470, 1471, 1478, 1472, 1488, 1481, + 1477, 1485, 1480, 1479, 1492, 1477, 1482, 1486, 1472, 1474, + + 1482, 1475, 0, 1479, 1478, 1491, 0, 1480, 1489, 1481, + 1483, 0, 1485, 1486, 1489, 1484, 1490, 0, 1485, 1494, + 1488, 1489, 1490, 1482, 1486, 1495, 1492, 1491, 1497, 1490, + 1493, 1496, 1491, 1500, 1494, 1489, 1503, 1493, 1495, 1501, + 1496, 1489, 1500, 1490, 1498, 1499, 1494, 1499, 1505, 1490, + 1502, 1498, 1495, 1509, 1497, 1497, 1508, 1493, 1496, 1502, + 1500, 1501, 0, 1503, 1504, 1507, 1501, 1509, 1504, 1508, + 1505, 1498, 1499, 1507, 1510, 1505, 1511, 1502, 1512, 1510, + 1509, 1513, 1514, 1508, 1515, 1511, 1516, 1512, 0, 1520, + 1517, 1504, 1507, 1517, 1519, 1523, 1546, 1515, 1516, 1513, + + 0, 1514, 1517, 1511, 1518, 1512, 1510, 1518, 1513, 1514, + 1521, 1515, 1519, 1516, 1520, 1525, 1520, 1517, 1524, 1526, + 1517, 1519, 1531, 1521, 1528, 1527, 1518, 1523, 1546, 1524, + 1527, 1518, 1528, 1532, 1518, 1526, 1533, 1521, 1525, 1529, + 1529, 1530, 1525, 1534, 1531, 1524, 1526, 1535, 0, 1531, + 1530, 1528, 1534, 1536, 1535, 1532, 1540, 1527, 1533, 1539, + 1532, 1542, 1537, 1533, 1541, 1540, 1529, 1543, 1530, 1537, + 1534, 1545, 1539, 1541, 1535, 1536, 1544, 1547, 0, 1545, + 1536, 0, 1548, 1540, 1551, 1544, 1539, 1542, 1542, 1537, + 1543, 1541, 1547, 1548, 1543, 1550, 1551, 1549, 1545, 1553, + + 1552, 1554, 0, 1544, 1547, 1549, 1557, 1553, 1550, 1548, + 1555, 1551, 1552, 1556, 1559, 1557, 1558, 0, 1562, 1560, + 1561, 1567, 1550, 1554, 1549, 1560, 1553, 1552, 1554, 1558, + 1555, 1564, 1568, 1557, 1566, 1556, 1559, 1555, 1561, 1563, + 1556, 1559, 1570, 1558, 1562, 1562, 1560, 1561, 1565, 1564, + 1569, 1563, 1571, 1567, 1573, 1565, 1574, 1572, 1564, 1576, + 1566, 1566, 1574, 1569, 1568, 1573, 1563, 1575, 1570, 1570, + 1577, 1578, 1579, 0, 1580, 1565, 0, 1569, 1572, 1571, + 1582, 1573, 1583, 1574, 1572, 0, 1584, 1585, 1589, 1575, + 1590, 1576, 0, 1580, 1575, 1580, 1585, 1586, 1579, 1579, + + 1580, 1580, 1577, 1578, 1584, 1583, 1587, 1582, 1589, 1583, + 1592, 1588, 1586, 1584, 1585, 1589, 1590, 1590, 1591, 1587, + 1580, 1593, 1580, 1588, 1586, 1591, 0, 1594, 1595, 1592, + 1597, 1596, 1604, 1587, 1599, 1597, 1600, 1592, 1588, 1596, + 1601, 1595, 1598, 1600, 1602, 1591, 1605, 1598, 1603, 1594, + 1604, 1609, 1602, 1593, 1594, 1595, 1603, 1599, 1596, 1604, + 1609, 1599, 1597, 1600, 1606, 1610, 1601, 1601, 1605, 1607, + 1612, 1602, 1606, 1605, 1598, 1603, 1608, 1607, 1609, 1611, + 1613, 1614, 1615, 1608, 1616, 1616, 1617, 1618, 1614, 1613, + 1620, 1606, 1619, 0, 1615, 1618, 1607, 1610, 1622, 1628, + + 0, 1611, 1612, 1608, 1621, 1628, 1611, 1613, 1614, 1615, + 1630, 1616, 1621, 1619, 1618, 1623, 1622, 1627, 1617, 1619, + 1624, 1625, 1620, 1623, 1626, 1622, 1628, 1629, 1624, 1625, + 1627, 1621, 1626, 1631, 1634, 1632, 1630, 1630, 1633, 1629, + 1635, 1636, 1623, 1632, 1627, 0, 1633, 1624, 1625, 1634, + 1637, 1626, 1638, 1641, 1629, 1639, 0, 1631, 1640, 1642, + 1631, 1634, 1632, 1647, 0, 1633, 1648, 1635, 1636, 1639, + 1640, 1641, 1637, 1642, 1645, 1638, 1650, 1637, 1645, 1638, + 1641, 1656, 1639, 1649, 1651, 1640, 1642, 1652, 1648, 1647, + 1647, 1645, 1649, 1648, 1653, 1657, 1655, 1654, 1658, 1645, + + 1650, 1645, 1651, 1650, 1654, 1645, 1653, 1655, 1656, 1652, + 1649, 1651, 1660, 1659, 1652, 1661, 1662, 1657, 1645, 1663, + 1669, 1653, 1657, 1655, 1654, 1659, 1660, 1664, 1665, 1668, + 1658, 1667, 1666, 1670, 1674, 1665, 1668, 1677, 1662, 1660, + 1659, 1666, 1663, 1662, 1672, 1675, 1663, 1661, 1676, 1667, + 1664, 1675, 1669, 1672, 1664, 1665, 1668, 1678, 1667, 1666, + 1670, 1679, 0, 1677, 1677, 1681, 1674, 1683, 1679, 1684, + 1676, 1672, 1675, 1685, 1686, 1676, 1687, 1690, 1689, 1691, + 1692, 0, 1694, 1690, 1685, 1686, 1691, 1687, 1679, 1678, + 1693, 1683, 1681, 1700, 1683, 1701, 1684, 1693, 1692, 1695, + + 1685, 1686, 1689, 1687, 1690, 1689, 1691, 1692, 1694, 1694, + 1696, 1695, 1697, 1698, 1699, 1702, 1696, 1693, 1704, 1703, + 1697, 1701, 1701, 1707, 1712, 1700, 1695, 1699, 1703, 1705, + 1704, 1705, 1710, 1702, 1708, 1698, 1706, 1696, 0, 1697, + 1698, 1699, 1702, 1706, 1709, 1704, 1703, 1708, 1711, 1707, + 1707, 1712, 1718, 1709, 1710, 1713, 1705, 1714, 1717, 1710, + 1711, 1708, 1715, 1706, 1714, 1716, 1717, 1719, 1718, 1720, + 1716, 1709, 1723, 1721, 1725, 1711, 1724, 1720, 1713, 1718, + 1727, 1724, 1713, 1726, 1714, 1717, 0, 0, 1715, 1715, + 1719, 0, 1716, 1728, 1719, 1721, 1720, 1726, 1725, 1723, + + 1721, 1725, 1727, 1729, 1728, 1730, 1732, 1727, 1724, 1733, + 1726, 1733, 1729, 1731, 1731, 1736, 1734, 1737, 1730, 1732, + 1728, 1731, 1735, 1738, 1737, 1742, 0, 1740, 1739, 1743, + 1729, 1741, 1730, 1732, 1734, 1739, 1733, 1736, 1744, 1741, + 1731, 1731, 1736, 1734, 1737, 1738, 1745, 1743, 1735, 1735, + 1738, 1740, 1742, 1745, 1740, 1739, 1743, 1746, 1741, 1747, + 1744, 1748, 1749, 1750, 1753, 1744, 0, 1754, 0, 1749, + 1751, 1755, 1756, 1745, 1757, 0, 1763, 1753, 1760, 1755, + 1756, 1747, 1746, 1758, 1746, 1761, 1747, 1762, 1775, 1749, + 1762, 1753, 1751, 1748, 1754, 1750, 1757, 1751, 1755, 1756, + + 1760, 1757, 1763, 1763, 1758, 1760, 1764, 1761, 1765, 1766, + 1758, 1767, 1761, 1768, 1762, 1769, 1770, 1772, 1766, 1771, + 1775, 1765, 0, 1767, 1772, 1770, 1783, 0, 1776, 1780, + 1785, 1779, 1764, 1764, 1771, 1765, 1766, 1768, 1767, 1774, + 1768, 1769, 1769, 1770, 1772, 1773, 1771, 1777, 1773, 1779, + 1776, 1780, 1782, 1783, 1774, 1776, 1780, 1781, 1779, 1781, + 1773, 1784, 1785, 1777, 1784, 1786, 1774, 1787, 1792, 1773, + 1790, 1777, 1773, 1788, 1777, 1773, 1782, 1789, 0, 1782, + 0, 1797, 1792, 1791, 1781, 1794, 0, 1773, 1784, 1787, + 1777, 1795, 1793, 1794, 1787, 1792, 1796, 1786, 1795, 1788, + + 1788, 1793, 1790, 1789, 1789, 1791, 1798, 1799, 1800, 1801, + 1791, 0, 1794, 1797, 0, 1803, 1804, 1802, 1795, 1793, + 1796, 1802, 1806, 1796, 1805, 1807, 1810, 1809, 1808, 0, + 1800, 1806, 1807, 0, 1810, 1800, 1809, 1803, 1798, 1799, + 1808, 1801, 1803, 1804, 1802, 1812, 1805, 1813, 1814, 1806, + 1811, 1805, 1807, 1810, 1809, 1808, 1815, 1811, 1812, 1817, + 1813, 1814, 1816, 1818, 1816, 1815, 1822, 1820, 1819, 1823, + 1825, 1824, 1812, 1826, 1813, 1814, 1819, 1811, 1829, 1834, + 1826, 1822, 1817, 1815, 1823, 1824, 1817, 1820, 1818, 1816, + 1818, 1829, 1827, 1822, 1820, 1819, 1823, 1828, 1824, 1830, + + 1826, 1831, 1825, 1827, 1828, 1829, 1834, 1832, 1835, 1836, + 0, 1838, 1842, 1841, 1837, 1835, 1841, 1830, 1839, 1827, + 1840, 1842, 0, 1830, 1828, 1832, 1830, 1831, 1831, 1837, + 1839, 1836, 1843, 1840, 1832, 1835, 1836, 1838, 1838, 1842, + 1841, 1837, 1844, 1845, 1830, 1839, 1847, 1840, 1846, 1847, + 1843, 1848, 1852, 1844, 1853, 1845, 1853, 1855, 1854, 1843, + 1850, 1852, 1848, 1856, 1847, 1850, 1844, 1859, 1846, 1844, + 1845, 1857, 1850, 1847, 1858, 1846, 1847, 1860, 1848, 1852, + 1844, 1853, 1854, 1858, 1855, 1854, 1857, 1850, 1861, 1860, + 1856, 1859, 1850, 1862, 1859, 1863, 1864, 1866, 1857, 1865, + + 1868, 1858, 0, 1863, 1860, 1867, 1868, 1862, 1869, 1865, + 1872, 1878, 1877, 1870, 1871, 1861, 1876, 0, 1864, 1866, + 1862, 1870, 1863, 1864, 1866, 1871, 1865, 1868, 1872, 1867, + 1869, 1873, 1867, 1874, 1876, 1869, 1874, 1872, 1878, 1873, + 1870, 1871, 1875, 1876, 1877, 1875, 1879, 1880, 1881, 1886, + 1882, 1874, 1883, 1884, 1880, 1887, 1885, 0, 1873, 1882, + 1874, 1885, 1881, 1874, 1884, 1883, 1879, 1892, 1893, 1875, + 1887, 1886, 1895, 1879, 1880, 1881, 1886, 1882, 1891, 1883, + 1884, 1890, 1887, 1890, 1897, 1894, 1898, 1891, 1885, 1898, + 1895, 1902, 1893, 1892, 1892, 1893, 1894, 1896, 1897, 1895, + + 0, 1896, 1899, 1900, 1898, 1891, 0, 0, 1890, 1901, + 1897, 1897, 1894, 1898, 1903, 1899, 1898, 1902, 1902, 1914, + 0, 1916, 1917, 1896, 1896, 1897, 1904, 1900, 1896, 1899, + 1900, 1901, 1907, 1905, 1906, 1904, 1901, 1907, 1903, 1905, + 1910, 1903, 1909, 1906, 1911, 1913, 1912, 1915, 1916, 1911, + 1919, 1914, 1910, 1904, 1917, 1909, 1915, 1918, 1913, 1920, + 1905, 1906, 1921, 1919, 1907, 1926, 1929, 1910, 1912, 1909, + 0, 1911, 1913, 1912, 1915, 1923, 1927, 1919, 1924, 1918, + 1925, 1931, 1923, 1921, 1918, 1924, 1928, 1933, 1934, 1921, + 1927, 1920, 1928, 1925, 1937, 1933, 1934, 1926, 1929, 1936, + + 1931, 1935, 1923, 1927, 1938, 1924, 1939, 1925, 1931, 1935, + 1928, 1940, 1942, 1928, 1933, 1934, 1937, 1943, 1936, 1928, + 1939, 1937, 1938, 1941, 1944, 1942, 1936, 1945, 1935, 1940, + 1943, 1938, 1946, 1939, 1947, 1948, 1949, 1941, 1940, 1942, + 1950, 1953, 1954, 1951, 1943, 1944, 1952, 1950, 1955, 1948, + 1941, 1944, 1951, 0, 1952, 1956, 1954, 1958, 1947, 1945, + 1956, 1947, 1948, 1949, 1946, 1957, 1958, 1950, 1953, 1954, + 1951, 1960, 1944, 1952, 1961, 1963, 1957, 1962, 1964, 0, + 1955, 1961, 1956, 1970, 1958, 1964, 1965, 1966, 1967, 1968, + 0, 0, 1957, 1968, 1970, 1972, 1974, 1963, 1960, 1973, + + 1962, 1961, 1963, 1975, 1962, 1964, 1967, 1970, 1965, 1966, + 1970, 1972, 1976, 1965, 1966, 1967, 1968, 1973, 1975, 1977, + 1974, 1970, 1972, 1974, 1976, 1978, 1973, 1979, 1980, 1981, + 1975, 1982, 1983, 1978, 1985, 1987, 1980, 1984, 0, 1976, + 1986, 1989, 1979, 1991, 1993, 1983, 1977, 1988, 1989, 1985, + 1987, 1991, 1978, 1982, 1979, 1980, 1981, 1984, 1982, 1983, + 1986, 1985, 1987, 1988, 1984, 1992, 1994, 1986, 1989, 1995, + 1991, 1997, 1992, 1996, 1988, 1998, 1993, 1999, 1995, 2000, + 2003, 1994, 2007, 2002, 1999, 0, 2006, 0, 2008, 2004, + 2005, 0, 1992, 1994, 1996, 2010, 1995, 2006, 1997, 1998, + + 1996, 2004, 1998, 2009, 1999, 2002, 2000, 2011, 2005, 0, + 2002, 2018, 2003, 2006, 2007, 2008, 2004, 2005, 2009, 2012, + 2010, 2016, 2010, 2013, 2014, 2017, 2012, 2015, 2013, 2018, + 2009, 2011, 2020, 2014, 2011, 2021, 2015, 0, 2018, 2022, + 2019, 2028, 2024, 2016, 2020, 2023, 2012, 2017, 2016, 2024, + 2013, 2014, 2017, 2025, 2015, 2019, 2026, 2021, 2023, 2020, + 2025, 2022, 2021, 2023, 2027, 2029, 2022, 2019, 2028, 2024, + 0, 2030, 2023, 2032, 2033, 2025, 2027, 2030, 2026, 2035, + 2025, 2034, 2033, 2026, 2032, 2023, 2036, 2025, 2039, 2034, + 2035, 2027, 2037, 2036, 2038, 2040, 2038, 2029, 2030, 2041, + + 2032, 2033, 2042, 2043, 2050, 2044, 2035, 2038, 2034, 2042, + 2045, 2048, 2046, 2036, 2039, 2039, 2045, 2037, 2046, 2037, + 2049, 2038, 2040, 2038, 2051, 2053, 2041, 2047, 2055, 2042, + 2043, 2044, 2044, 2047, 2057, 2054, 2050, 2045, 2048, 2046, + 2061, 2056, 2058, 2049, 2054, 2056, 2060, 2049, 2051, 2062, + 2063, 2051, 2057, 2059, 2047, 2059, 2062, 2053, 2064, 2065, + 2055, 2057, 2054, 2069, 2058, 2067, 2068, 2061, 2056, 2058, + 2060, 2065, 2063, 2060, 2070, 2066, 2062, 2063, 2071, 0, + 2059, 2066, 2076, 0, 2073, 2064, 2065, 2067, 2068, 2069, + 2069, 2073, 2067, 2068, 2074, 2080, 2070, 2072, 2072, 2072, + + 2075, 2070, 2066, 2074, 2072, 0, 2077, 2075, 2078, 2079, + 2071, 2073, 2072, 2077, 2076, 2078, 2084, 2080, 2082, 2083, + 2085, 2074, 2080, 2082, 2072, 2072, 2072, 2075, 2084, 2079, + 2087, 2072, 2083, 2077, 2088, 2078, 2079, 2086, 2089, 0, + 2094, 2090, 2087, 2084, 2092, 2085, 2083, 2085, 2090, 2091, + 2082, 2096, 2092, 2086, 2093, 2100, 2089, 2087, 2095, 2095, + 2093, 2099, 2091, 2097, 2086, 2089, 2088, 2094, 2090, 2098, + 2097, 2092, 2101, 2102, 2098, 2105, 2091, 2096, 2096, 2107, + 2102, 2093, 2100, 2108, 2106, 2095, 2106, 2099, 2099, 2110, + 2097, 2112, 2111, 2117, 2115, 2113, 2098, 2107, 2111, 2101, + + 2102, 2113, 2105, 2118, 2114, 2115, 2107, 2110, 2120, 2118, + 2108, 2106, 2114, 2116, 2121, 2119, 2110, 2122, 2122, 2111, + 2117, 2115, 2113, 2112, 2123, 2124, 2116, 2119, 2120, 2128, + 2118, 2114, 2121, 2125, 2125, 2120, 2126, 2129, 2130, 2131, + 2116, 2121, 2119, 2133, 2122, 2132, 2131, 2126, 2137, 2134, + 2123, 2123, 2124, 0, 2136, 2138, 2139, 2141, 0, 2129, + 2125, 2128, 2136, 2126, 2129, 2132, 2131, 2140, 0, 2141, + 2130, 0, 2132, 2144, 2134, 2133, 2134, 2145, 2139, 2142, + 2137, 2136, 2138, 2139, 2141, 2140, 2142, 2143, 2146, 2147, + 2148, 2148, 2145, 2149, 2140, 2143, 2151, 2144, 2147, 2150, + + 2144, 2152, 2154, 2151, 2145, 2155, 2142, 2163, 0, 2153, + 0, 2156, 2146, 2157, 2143, 2146, 2147, 2148, 2156, 2149, + 2149, 0, 2150, 2151, 2153, 2157, 2150, 2158, 2154, 2154, + 2161, 2162, 2160, 2152, 2163, 2161, 2153, 2155, 2156, 2160, + 2157, 2164, 2169, 2158, 2164, 2170, 2171, 2165, 2166, 2173, + 2158, 2177, 0, 2162, 2158, 2165, 2168, 2161, 2162, 2160, + 2166, 2172, 2174, 2175, 2168, 2169, 2185, 2171, 2164, 2169, + 2158, 2170, 2170, 2171, 2165, 2166, 2173, 2176, 2177, 2172, + 2174, 2178, 2176, 2168, 2179, 2181, 2175, 2178, 2172, 2174, + 2175, 2180, 2190, 2176, 2182, 2183, 2184, 2179, 2185, 2180, + + 2191, 2182, 2183, 2184, 2176, 2186, 2188, 2181, 2178, 2176, + 2189, 2179, 2181, 2187, 2186, 2192, 2194, 2197, 2180, 2190, + 2198, 2182, 2183, 2184, 2189, 2187, 2191, 2191, 2188, 2196, + 2195, 2200, 2186, 2188, 2194, 2195, 2196, 2189, 2192, 2197, + 2187, 2202, 2192, 2194, 2197, 2201, 2195, 2198, 2204, 2206, + 2201, 2205, 2205, 2208, 2207, 2210, 2196, 2195, 2200, 2212, + 2211, 2215, 2195, 2213, 2214, 2217, 2214, 2216, 2220, 2207, + 2210, 2206, 2216, 2202, 2212, 0, 2206, 2201, 2205, 2219, + 2204, 2207, 2210, 2211, 2218, 2208, 2212, 2211, 2223, 2213, + 2213, 2214, 2221, 2215, 2216, 2220, 2218, 2217, 2222, 2224, + + 2221, 2219, 2226, 0, 2227, 2222, 2219, 2230, 2228, 2231, + 2223, 2218, 2227, 2232, 2224, 2223, 2233, 2226, 2234, 2221, + 2235, 2236, 2239, 0, 2241, 2222, 2224, 0, 2245, 2226, + 2228, 2227, 0, 2231, 2230, 2228, 2231, 2237, 2240, 2232, + 2232, 2238, 2242, 2233, 2234, 2234, 2241, 2235, 2238, 2237, + 2245, 2241, 2243, 2236, 2239, 2245, 2246, 2248, 2251, 2240, + 2249, 2246, 2252, 2242, 2237, 2240, 2250, 2255, 2238, 2242, + 2243, 2253, 2250, 2251, 2252, 2256, 2258, 2257, 2259, 2243, + 2263, 2248, 2255, 2249, 2248, 2251, 2260, 2249, 2246, 2252, + 2256, 2262, 2261, 2250, 2255, 2268, 2259, 2253, 2253, 2257, + + 2271, 2266, 2256, 2258, 2257, 2259, 2265, 2263, 2260, 2264, + 2266, 2269, 2267, 2260, 2261, 2262, 2264, 2272, 2262, 2261, + 2267, 2270, 2273, 2281, 2265, 0, 2272, 2268, 2266, 2275, + 2281, 2282, 2271, 2265, 2269, 2279, 2264, 2274, 2269, 2267, + 2273, 2277, 2275, 2270, 2272, 2278, 2274, 2280, 2270, 2273, + 2281, 2283, 2277, 2279, 2278, 2284, 2275, 2282, 2282, 2286, + 2285, 2287, 2279, 2290, 2274, 2280, 2285, 2277, 2277, 2283, + 2284, 2292, 2278, 2293, 2280, 2287, 2299, 2297, 2283, 2277, + 2294, 2286, 2284, 2295, 2293, 2301, 2286, 2285, 2287, 2297, + 2290, 2294, 2298, 2300, 2295, 2292, 2302, 2304, 2292, 2306, + + 2293, 2303, 2309, 2300, 2297, 2298, 2305, 2294, 2299, 2310, + 2295, 2301, 2301, 2307, 2303, 2305, 2313, 2314, 2304, 2298, + 2300, 2302, 0, 2302, 2304, 2315, 2306, 2312, 2303, 2309, + 2316, 2312, 2307, 2305, 2317, 2310, 2310, 2313, 2315, 2317, + 2307, 2318, 2330, 2313, 2319, 2321, 2330, 2320, 2318, 2314, + 2316, 2321, 2315, 2324, 2312, 2320, 0, 2316, 2326, 2326, + 2322, 2317, 2323, 2325, 2328, 2324, 2327, 0, 2318, 2330, + 2319, 2319, 2321, 2320, 2320, 2322, 2328, 2323, 2325, 2334, + 2324, 2329, 2320, 2334, 2327, 2326, 2329, 2322, 2336, 2323, + 2325, 2328, 0, 2327, 2331, 2331, 2333, 2335, 2331, 2337, + + 2338, 0, 2342, 2333, 2339, 0, 2334, 2338, 2337, 2341, + 2340, 2331, 2335, 2329, 0, 2336, 2346, 2345, 0, 2331, + 0, 2331, 2331, 2333, 2335, 2331, 2337, 2338, 2339, 2342, + 2348, 2339, 2340, 2343, 2349, 2341, 2341, 2340, 2331, 2345, + 2343, 2346, 2347, 2346, 2345, 2352, 2354, 2355, 2362, 2357, + 2358, 2347, 2348, 0, 2349, 2354, 2360, 2348, 2359, 0, + 2343, 2349, 2365, 2352, 2357, 2355, 2359, 2377, 2360, 2347, + 2367, 2361, 2352, 2354, 2355, 2358, 2357, 2358, 2361, 2363, + 2362, 2366, 2369, 2360, 2374, 2359, 2363, 2365, 2370, 2365, + 2368, 2368, 2372, 2374, 2366, 2376, 2373, 2367, 2361, 2377, + + 0, 2375, 2376, 2378, 2369, 2380, 2363, 2379, 2366, 2369, + 2375, 2374, 2382, 2370, 2372, 2370, 2387, 2368, 2373, 2372, + 2380, 2379, 2376, 2373, 2381, 2378, 2386, 2384, 2375, 2381, + 2378, 2382, 2380, 2385, 2379, 2384, 2388, 2390, 2391, 2382, + 2392, 2386, 2389, 2387, 2393, 2391, 2385, 2395, 2394, 2390, + 2396, 2398, 2399, 2386, 2384, 0, 2381, 0, 2389, 2397, + 2385, 2401, 2388, 2388, 2390, 2391, 2393, 2403, 2397, 2389, + 2400, 2393, 2392, 2394, 2404, 2394, 2402, 2405, 2400, 2395, + 2406, 2407, 2396, 2398, 2399, 0, 2397, 2409, 2401, 2400, + 2407, 2402, 2411, 2403, 2403, 2405, 2465, 2400, 2414, 2468, + + 2404, 2404, 2406, 2402, 2405, 2400, 2410, 2406, 2407, 2410, + 2409, 2413, 2412, 2414, 2409, 2416, 2413, 2411, 2412, 2411, + 2415, 2418, 2419, 2420, 2410, 2414, 2423, 2426, 2465, 2421, + 2416, 2468, 2427, 2410, 2425, 2418, 2410, 2419, 2415, 2412, + 2423, 2427, 2416, 2413, 0, 2420, 2424, 2415, 2418, 2419, + 2420, 2421, 2425, 2423, 2426, 2428, 2421, 2429, 2424, 2427, + 2430, 2425, 2432, 2436, 2428, 2424, 2429, 2431, 2433, 2431, + 2434, 2430, 2438, 2424, 2439, 2432, 2437, 0, 2436, 2438, + 2433, 0, 2428, 2440, 2429, 2424, 2441, 2430, 2447, 2432, + 2436, 2437, 2434, 2442, 2431, 2433, 2439, 2434, 2445, 2438, + + 2453, 2439, 2442, 2437, 2441, 2440, 2449, 2450, 2448, 2447, + 2440, 2445, 2448, 2441, 2452, 2447, 2450, 2455, 2449, 2445, + 2442, 2451, 2454, 2451, 2458, 2445, 0, 2453, 2456, 2460, + 2459, 2457, 2452, 2449, 2450, 2448, 2469, 2456, 2445, 2457, + 2454, 2452, 2461, 2460, 2455, 2466, 2462, 2458, 2451, 2454, + 2466, 2458, 2459, 2462, 2461, 2456, 2460, 2459, 2457, 2464, + 2467, 2470, 2472, 2473, 2475, 2467, 2478, 2464, 2469, 2461, + 2473, 2475, 2466, 2462, 2477, 2478, 2479, 2481, 2477, 0, + 2480, 2472, 2482, 2488, 2483, 2470, 2464, 2484, 2470, 2472, + 2473, 2475, 2467, 2478, 2480, 2481, 2486, 2491, 2496, 2485, + + 2489, 2477, 2484, 2479, 2481, 2480, 2480, 2480, 2485, 2482, + 2483, 2483, 2489, 2490, 2484, 2488, 2492, 2486, 2493, 2491, + 2490, 2480, 2494, 2486, 2491, 2492, 2485, 2489, 2495, 2498, + 2496, 2499, 2480, 0, 2500, 2501, 0, 2503, 2499, 2503, + 2490, 2504, 2501, 2492, 2493, 2493, 2511, 2505, 2506, 2494, + 2495, 2505, 2498, 2511, 0, 2495, 2498, 2500, 2499, 2508, + 2506, 2500, 2501, 2504, 2503, 2512, 2510, 2507, 2504, 2509, + 2514, 2516, 2515, 2511, 2505, 2506, 2507, 2510, 2509, 2513, + 2517, 2508, 2518, 2516, 2513, 2521, 2508, 2512, 2519, 2519, + 0, 2518, 2512, 2510, 2507, 2515, 2509, 2514, 2516, 2515, + + 2521, 2520, 2517, 2522, 2523, 2524, 2513, 2517, 2525, 2518, + 2520, 2522, 2521, 2526, 2528, 2519, 2529, 2525, 2532, 2524, + 2533, 2530, 2532, 2533, 2529, 2538, 2523, 2540, 2520, 2530, + 2522, 2523, 2524, 2528, 2531, 2525, 2534, 2546, 2536, 2542, + 2526, 2528, 2531, 2529, 2534, 2532, 2535, 2533, 2530, 2537, + 2539, 2542, 2535, 2536, 2545, 2537, 2544, 2538, 2546, 2540, + 2547, 2531, 2548, 2534, 2546, 2536, 2542, 2545, 2539, 2548, + 2544, 2549, 2550, 2535, 2552, 0, 2537, 2539, 2551, 2553, + 2554, 2545, 2553, 2544, 2556, 2547, 2555, 2547, 2552, 2548, + 2557, 2558, 2559, 2554, 2550, 0, 2560, 2561, 2549, 2550, + + 2555, 2552, 2551, 2565, 2570, 2551, 2553, 2554, 2560, 2561, + 2556, 2556, 2562, 2555, 2566, 2567, 2558, 2557, 2558, 2559, + 2568, 0, 2563, 2560, 2561, 2563, 2562, 2567, 2571, 2572, + 2565, 2570, 2569, 2580, 2581, 2569, 2574, 2575, 2576, 2562, + 2566, 2566, 2567, 2578, 2575, 2576, 2568, 2568, 2563, 2563, + 2569, 2572, 2563, 2577, 2583, 2571, 2572, 2578, 2574, 2569, + 2580, 2581, 2569, 2574, 2575, 2576, 2582, 2584, 2577, 2585, + 2578, 2586, 2588, 2587, 2582, 2589, 2584, 2590, 2592, 2591, + 2577, 2583, 2593, 2586, 2595, 2592, 2600, 0, 0, 0, + 2590, 2594, 2599, 2582, 2584, 2587, 2585, 2591, 2586, 2588, + + 2587, 2594, 2589, 2596, 2590, 2592, 2591, 2597, 2593, 2593, + 2602, 2595, 2601, 2600, 2599, 2597, 2596, 2603, 2594, 2599, + 2601, 2604, 2606, 2608, 2605, 2609, 2603, 2607, 2610, 2616, + 2596, 2611, 2615, 2609, 2597, 2613, 0, 2602, 0, 2601, + 2610, 0, 2607, 2604, 2603, 2605, 2606, 2613, 2604, 2606, + 2608, 2605, 2609, 2607, 2607, 2610, 2611, 2614, 2611, 2615, + 2618, 2616, 2613, 2619, 2620, 2614, 2621, 2618, 2620, 2607, + 2623, 2622, 2624, 2627, 2625, 2619, 2626, 2630, 2621, 2628, + 2624, 2625, 2633, 2626, 2614, 3712, 3712, 2618, 0, 2630, + 2619, 2620, 0, 2621, 2622, 2627, 2629, 2623, 2622, 2624, + + 2627, 2625, 2628, 2626, 2630, 2629, 2628, 2631, 2634, 2633, + 2635, 2636, 2629, 2629, 3712, 2634, 2637, 2638, 2642, 2639, + 2629, 2631, 2643, 2629, 2636, 2637, 2638, 2640, 2640, 2641, + 2635, 2639, 2629, 2631, 2631, 2634, 2642, 2635, 2636, 2629, + 2629, 2646, 2644, 2637, 2638, 2642, 2639, 2643, 2631, 2643, + 2647, 0, 2648, 2649, 2640, 2641, 2641, 2644, 2652, 2644, + 2650, 2651, 2653, 2651, 0, 2647, 2644, 2662, 2653, 2644, + 2655, 2658, 2652, 2646, 2648, 2649, 2654, 2647, 2659, 2648, + 2649, 2663, 2650, 2661, 2644, 2652, 2644, 2650, 2651, 2653, + 2656, 2656, 2655, 2658, 2654, 2661, 2660, 2655, 2658, 2662, + + 2659, 2664, 2665, 2654, 2666, 2659, 0, 2664, 2667, 2678, + 2661, 2668, 2670, 2663, 2665, 2672, 2671, 2656, 2660, 2669, + 0, 2669, 2672, 2660, 2677, 2679, 2670, 2673, 2664, 2665, + 2667, 2674, 2675, 2668, 2676, 2667, 2666, 2677, 2668, 2670, + 2671, 2678, 2672, 2671, 2680, 2673, 2669, 2685, 2682, 2674, + 2675, 2677, 2676, 2684, 2673, 2682, 2686, 2679, 2674, 2675, + 2684, 2676, 2687, 0, 2688, 2685, 2692, 2680, 2689, 2691, + 2696, 2680, 2688, 2690, 2685, 2682, 2698, 0, 2697, 2693, + 2684, 2696, 2686, 2686, 2689, 2724, 0, 2691, 2715, 2697, + 2688, 2688, 2692, 2692, 2687, 2689, 2691, 2696, 2690, 2688, + + 2690, 2693, 2694, 2698, 2694, 2697, 2693, 2699, 2700, 2694, + 2701, 2702, 2705, 2706, 2703, 2715, 0, 2724, 2708, 2699, + 2707, 2711, 2710, 2725, 2706, 2716, 2700, 2705, 2701, 2694, + 2702, 2694, 2707, 2708, 2699, 2700, 2703, 2701, 2702, 2705, + 2706, 2703, 2713, 2711, 2712, 2708, 2710, 2707, 2711, 2710, + 2714, 2712, 2716, 2717, 2718, 2725, 2719, 2721, 0, 0, + 2713, 2718, 2722, 2723, 2727, 2714, 2728, 0, 2729, 2713, + 2726, 2712, 2730, 0, 2731, 2735, 2734, 2714, 0, 2728, + 2717, 2718, 2719, 2719, 2721, 2723, 2722, 2730, 2726, 2722, + 2723, 2727, 2732, 2728, 2729, 2729, 2733, 2726, 2736, 2730, + + 2731, 2731, 2734, 2734, 2733, 2732, 2737, 2735, 2739, 2741, + 2740, 2736, 0, 0, 2744, 2748, 2742, 2743, 0, 2732, + 2746, 0, 2745, 2733, 2751, 2736, 0, 2746, 2737, 2747, + 2759, 2739, 2744, 2737, 2740, 2739, 2741, 2740, 2742, 2743, + 2745, 2744, 2748, 2742, 2743, 2749, 2751, 2746, 2752, 2745, + 2753, 2751, 2747, 2754, 2755, 2752, 2747, 2753, 2757, 2749, + 2754, 2756, 2759, 2761, 2758, 2757, 2760, 2755, 2763, 2764, + 2762, 2765, 2749, 0, 2766, 2752, 2769, 2753, 2764, 2765, + 2754, 2755, 2766, 2767, 2756, 2757, 2758, 2760, 2756, 2761, + 2761, 2758, 2762, 2760, 2763, 2763, 2764, 2762, 2765, 2771, + + 2768, 2766, 2772, 2769, 2774, 2767, 2768, 2775, 2773, 0, + 2767, 2781, 2795, 2772, 2771, 2776, 2777, 0, 2782, 2779, + 0, 2783, 0, 0, 2781, 2784, 2771, 2768, 2785, 2772, + 2773, 2782, 2787, 2789, 2776, 2773, 2774, 2779, 2781, 2775, + 2791, 2777, 2776, 2777, 2795, 2782, 2779, 2783, 2783, 2784, + 2788, 2794, 2784, 2796, 2785, 2785, 2787, 2789, 2797, 2787, + 2789, 2798, 2788, 2790, 2790, 2799, 2791, 2791, 2796, 2802, + 2806, 2807, 2804, 2810, 2794, 2811, 2811, 2788, 2794, 2798, + 2796, 2804, 2807, 2806, 2812, 2797, 2816, 2799, 2798, 2818, + 2790, 2820, 2799, 2817, 2813, 2810, 2802, 2806, 2807, 2804, + + 2810, 2814, 2811, 2813, 2822, 2823, 2825, 2814, 2816, 0, + 2812, 2812, 2823, 2816, 2824, 2817, 2818, 2825, 2820, 2826, + 2817, 2813, 2827, 2829, 2826, 0, 2833, 2830, 2814, 0, + 2831, 2829, 2823, 2825, 2837, 2838, 2822, 2832, 2836, 2839, + 2824, 2824, 2842, 0, 2827, 2831, 2826, 2835, 2839, 2827, + 2829, 2830, 2832, 2833, 2830, 2837, 2836, 2831, 2835, 2840, + 2843, 2837, 2844, 2846, 2832, 2836, 2839, 2838, 2845, 2842, + 2847, 2840, 2848, 2850, 2835, 2851, 2849, 2856, 2843, 0, + 2844, 2855, 2847, 2851, 2848, 0, 2840, 2843, 2846, 2844, + 2846, 2850, 2845, 2852, 2852, 2845, 2853, 2847, 2849, 2848, + + 2850, 2852, 2851, 2849, 2856, 2853, 2857, 2855, 2855, 2858, + 2860, 2859, 2861, 0, 2863, 2862, 2865, 2864, 2858, 2867, + 2852, 2852, 2870, 2853, 2860, 2866, 2867, 2863, 2857, 2859, + 2864, 2865, 2869, 2857, 2861, 2872, 2858, 2860, 2859, 2861, + 2862, 2863, 2862, 2865, 2864, 2871, 2867, 2866, 2868, 2870, + 2873, 2874, 2866, 2875, 2869, 2868, 2876, 2871, 2877, 2869, + 2878, 2882, 2872, 2879, 0, 2880, 2883, 2877, 2875, 2881, + 0, 2884, 2871, 2883, 0, 2868, 2882, 2873, 2874, 2888, + 2875, 2876, 2878, 2876, 2890, 2877, 2884, 2878, 2882, 2879, + 2879, 2880, 2880, 2883, 2885, 2881, 2881, 2886, 2884, 2887, + + 2889, 2885, 2891, 2886, 2892, 2893, 2888, 2894, 2889, 2897, + 2887, 2890, 0, 2895, 2901, 2896, 2897, 2898, 2899, 2902, + 2892, 2885, 2894, 2903, 2886, 2899, 2887, 2889, 2900, 2891, + 2896, 2892, 2893, 2895, 2894, 2900, 2897, 2902, 2906, 2898, + 2895, 2901, 2896, 2909, 2898, 2899, 2902, 2904, 2904, 2905, + 2903, 2907, 2906, 2908, 2907, 2900, 2905, 2910, 2911, 2915, + 0, 2909, 2912, 2911, 2913, 2906, 2908, 2914, 0, 2916, + 2909, 2917, 2910, 2919, 2904, 2923, 2905, 2915, 2907, 2913, + 2908, 2916, 2919, 2917, 2910, 2911, 2915, 2912, 2922, 2912, + 2920, 2913, 2921, 2914, 2914, 2920, 2916, 2921, 2917, 2924, + + 2919, 2925, 2923, 2924, 2929, 2926, 2930, 2927, 2928, 2931, + 2922, 2932, 0, 0, 2937, 2922, 2939, 2920, 2926, 2921, + 0, 2936, 0, 0, 2931, 2925, 2924, 0, 2925, 2927, + 2928, 2929, 2926, 2930, 2927, 2928, 2931, 2932, 2932, 2936, + 2937, 2937, 2939, 2939, 2940, 2941, 2942, 2943, 2936, 2945, + 2947, 2946, 2950, 2940, 2942, 2947, 2945, 2948, 2949, 2943, + 2946, 2941, 2951, 2952, 2948, 2949, 0, 2956, 2953, 2951, + 2950, 2940, 2941, 2942, 2943, 2953, 2945, 2947, 2946, 2950, + 2958, 2959, 2954, 2955, 2948, 2949, 2960, 2962, 2952, 2951, + 2952, 2954, 2955, 2956, 2956, 2953, 2961, 2963, 2965, 2960, + + 2966, 2961, 2967, 2958, 0, 2962, 2968, 2958, 2959, 2954, + 2955, 2967, 2969, 2960, 2962, 2968, 2965, 2970, 2971, 2972, + 2978, 2969, 2973, 2961, 2963, 2965, 2975, 2966, 2972, 2967, + 2971, 2973, 2974, 2968, 2975, 2976, 2979, 2970, 2977, 2969, + 2978, 2980, 2982, 2974, 2970, 2971, 2972, 2978, 2981, 2973, + 2983, 2982, 2985, 2975, 2986, 2981, 2987, 2988, 2976, 2974, + 2990, 2977, 2976, 2979, 2989, 2977, 2988, 2992, 2980, 2982, + 2991, 2983, 2990, 2989, 2993, 2981, 2994, 2983, 2991, 2985, + 2992, 2986, 2995, 2996, 2988, 2997, 2998, 2990, 2987, 2995, + 2996, 2989, 2997, 3000, 2992, 2999, 2993, 2991, 3002, 3001, + + 3000, 2993, 2998, 2994, 3003, 3004, 3005, 3007, 3008, 2995, + 2996, 2999, 2997, 2998, 3012, 3007, 3011, 0, 3010, 3015, + 3000, 3001, 2999, 3002, 3011, 3002, 3001, 3014, 3017, 3012, + 3004, 3003, 3004, 3005, 3007, 3008, 3010, 3013, 3025, 3024, + 3016, 3012, 0, 3011, 3013, 3010, 3015, 3016, 3019, 3014, + 3017, 3018, 3022, 3023, 3014, 3017, 3019, 3026, 3018, 3022, + 3028, 3027, 3023, 3024, 3013, 3025, 3024, 3016, 3031, 3026, + 3027, 3030, 3037, 3029, 3033, 3019, 3035, 0, 3018, 3022, + 3023, 3034, 3036, 3030, 3026, 3043, 3033, 3028, 3027, 3029, + 3038, 3031, 3040, 3034, 0, 3031, 3041, 3035, 3030, 3037, + + 3029, 3033, 3042, 3035, 3038, 3036, 3040, 0, 3034, 3036, + 3041, 3045, 3043, 3046, 3042, 3052, 3047, 3038, 3048, 3040, + 3044, 3044, 3046, 3041, 3049, 3048, 3051, 3050, 0, 3042, + 3047, 3045, 3049, 3051, 3044, 3054, 3056, 3055, 3045, 3057, + 3046, 3058, 3052, 3047, 3059, 3048, 3050, 3044, 3044, 3060, + 3054, 3049, 3059, 3051, 3050, 3055, 3061, 3062, 3063, 3056, + 3066, 3075, 3054, 3056, 3055, 3057, 3057, 3064, 3058, 3063, + 3065, 3059, 3072, 3068, 3073, 3062, 3060, 3065, 3061, 3068, + 3082, 3074, 3064, 3061, 3062, 3063, 3074, 3066, 3075, 3076, + 3077, 3078, 3073, 3079, 3064, 3080, 3081, 3065, 3072, 3072, + + 3068, 3073, 3083, 3076, 3077, 3078, 3086, 3082, 3074, 3083, + 3089, 3079, 3084, 3080, 3081, 3092, 3076, 3077, 3078, 3091, + 3079, 3093, 3080, 3081, 3084, 3094, 3095, 3096, 3092, 3083, + 3097, 0, 3089, 3086, 3095, 3099, 3101, 3089, 3102, 3084, + 0, 3091, 3092, 3093, 3094, 3096, 3091, 3099, 3093, 3097, + 3104, 3105, 3094, 3095, 3096, 3103, 3107, 3097, 3101, 3106, + 3102, 0, 3099, 3101, 3109, 3102, 3108, 3103, 3107, 3110, + 3111, 3113, 3109, 3112, 3115, 3114, 3118, 3104, 3105, 0, + 3113, 3106, 3103, 3107, 3114, 3116, 3106, 3117, 3108, 3118, + 3111, 3109, 3120, 3108, 3122, 3112, 3110, 3111, 3113, 3121, + + 3112, 3123, 3114, 3118, 3124, 3127, 3115, 3116, 3128, 3117, + 3129, 3121, 3116, 3130, 3117, 3131, 3122, 3135, 3120, 3120, + 3132, 3122, 3128, 3129, 3133, 3132, 3121, 3127, 3123, 3136, + 3135, 3124, 3127, 3134, 0, 3128, 3137, 3129, 0, 3131, + 3130, 3141, 3131, 3138, 3135, 3139, 3133, 3144, 3140, 3145, + 3142, 3133, 3132, 3141, 0, 3134, 3143, 3148, 3146, 3137, + 3134, 3136, 3143, 3137, 3152, 3138, 3140, 3139, 3141, 3142, + 3138, 3147, 3139, 3150, 3151, 3140, 0, 3142, 3159, 3144, + 3146, 3145, 3154, 3143, 3148, 3146, 3147, 3159, 3152, 3156, + 3157, 3152, 3158, 3150, 3160, 3161, 3151, 3154, 3147, 3163, + + 3150, 3151, 3162, 3166, 3165, 3159, 3164, 3172, 3160, 3154, + 3167, 3156, 3157, 3161, 3158, 3171, 3156, 3157, 0, 3158, + 3162, 3160, 3161, 0, 3164, 3163, 3163, 3165, 3172, 3162, + 3170, 3165, 3167, 3164, 3172, 3166, 3175, 3167, 3176, 3170, + 3179, 3177, 3178, 3181, 3175, 3176, 3180, 3171, 3177, 3185, + 3178, 3181, 3186, 3183, 3184, 3189, 3187, 3170, 3199, 0, + 0, 3197, 3200, 3175, 3186, 3176, 3180, 3179, 3177, 3178, + 3181, 3183, 3184, 3180, 3187, 3185, 3185, 3188, 3190, 3186, + 3183, 3184, 3189, 3187, 3192, 3194, 3190, 3196, 3197, 3188, + 3199, 3198, 3194, 3198, 3200, 3202, 3192, 3203, 3204, 3205, + + 3206, 3208, 3210, 3202, 3188, 3190, 3203, 3207, 3213, 3207, + 3196, 3192, 3194, 0, 3196, 3214, 3218, 3211, 3198, 3206, + 3210, 0, 3202, 3208, 3203, 3215, 3205, 3206, 3208, 3210, + 3204, 3211, 3216, 3217, 3207, 3219, 0, 3221, 0, 3214, + 3213, 3216, 3214, 3218, 3211, 3222, 3217, 3219, 3215, 3223, + 3229, 3228, 3215, 3227, 3226, 3229, 3224, 3230, 3231, 3216, + 3217, 3233, 3219, 3221, 3221, 3224, 3227, 3222, 3226, 3228, + 3232, 3223, 3222, 3234, 3232, 3236, 3223, 3229, 3228, 3230, + 3227, 3226, 3237, 3224, 3230, 3231, 3238, 3241, 3233, 3239, + 3244, 3243, 3254, 0, 3246, 3245, 3247, 3232, 3243, 3246, + + 3234, 0, 3236, 3252, 0, 3237, 3255, 3239, 3238, 3237, + 3245, 3247, 3244, 3238, 3241, 3256, 3239, 3244, 3243, 3254, + 3249, 3250, 3245, 3247, 3251, 3257, 3246, 3249, 3250, 3252, + 3252, 3251, 3258, 3255, 3261, 3262, 3259, 3265, 3264, 0, + 3266, 3267, 3256, 3268, 3262, 3264, 3258, 3249, 3250, 3257, + 3259, 3251, 3257, 3269, 3273, 3268, 3274, 3270, 3280, 3258, + 3271, 3261, 3262, 3259, 3265, 3264, 3266, 3266, 3267, 3271, + 3268, 3270, 3272, 3275, 3278, 3281, 3283, 3279, 3284, 3278, + 3269, 3283, 3284, 3274, 3270, 3272, 3273, 3271, 3285, 3287, + 3280, 3286, 3288, 3289, 3290, 3285, 3275, 3281, 3286, 3272, + + 3275, 3279, 3281, 3293, 3279, 3284, 3278, 3291, 3283, 3291, + 3287, 3296, 3292, 3298, 3297, 3285, 3287, 3309, 3286, 3301, + 3303, 3304, 3303, 3300, 3288, 3289, 3290, 3305, 0, 0, + 3293, 0, 0, 3298, 3291, 3292, 3297, 3307, 3296, 3292, + 3298, 3297, 3300, 3301, 3309, 3304, 3301, 3303, 3304, 3308, + 3300, 3306, 3306, 3305, 3305, 3310, 3311, 3312, 3308, 3307, + 3313, 3306, 3310, 3319, 3307, 3322, 3314, 3315, 3319, 3311, + 3317, 0, 3323, 3313, 3314, 0, 3308, 3316, 3306, 3306, + 3315, 3320, 3310, 3311, 3312, 3316, 3320, 3313, 3321, 3317, + 3314, 3324, 3322, 3314, 3315, 3319, 3321, 3317, 3323, 3323, + + 3325, 3314, 3326, 3328, 3316, 3327, 0, 3331, 3331, 3330, + 0, 3329, 3334, 3320, 3328, 3321, 3330, 3324, 3324, 3332, + 3333, 3335, 0, 3337, 3338, 3334, 3325, 3325, 3326, 3326, + 3328, 3327, 3327, 3329, 3331, 3343, 3330, 3332, 3329, 3334, + 3333, 3336, 3338, 3335, 3344, 3337, 3332, 3333, 3335, 3336, + 3337, 3338, 3339, 3340, 3341, 0, 3347, 3346, 3345, 3339, + 3340, 3341, 3343, 3350, 3352, 3348, 3349, 3353, 3336, 3346, + 3354, 3344, 3350, 3355, 3357, 3360, 0, 0, 3358, 3339, + 3340, 3341, 3345, 3347, 3346, 3345, 3348, 3353, 3349, 3359, + 3350, 3352, 3348, 3349, 3353, 3355, 3358, 3354, 3365, 3361, + + 3355, 3357, 3360, 3362, 3364, 3358, 3366, 3359, 3370, 3367, + 3368, 3369, 0, 3364, 0, 3371, 3359, 3361, 3373, 3369, + 3375, 3362, 3372, 3373, 3370, 3365, 3361, 3371, 3368, 3372, + 3362, 3364, 3367, 3366, 3375, 3370, 3367, 3368, 3369, 3376, + 3377, 3378, 3371, 0, 3380, 0, 3379, 3375, 3382, 3372, + 3373, 3384, 3377, 3378, 3381, 3383, 3391, 3376, 3390, 3394, + 0, 0, 3386, 3384, 3399, 0, 3376, 3377, 3378, 3379, + 3380, 3380, 3382, 3379, 3386, 3382, 3381, 3383, 3384, 3392, + 3390, 3381, 3383, 3391, 3395, 3390, 3394, 3397, 3396, 3386, + 3396, 3399, 3392, 3400, 3401, 3402, 3397, 3395, 3403, 3407, + + 3412, 3407, 3408, 3411, 3409, 0, 3392, 0, 3414, 0, + 3411, 3395, 3401, 3403, 3397, 3396, 3418, 3419, 0, 3420, + 3400, 3401, 3409, 3414, 3408, 3403, 3407, 3402, 3416, 3408, + 3411, 3409, 3412, 3421, 3416, 3414, 3423, 3424, 3418, 3419, + 3426, 3428, 3431, 3418, 3419, 3420, 3420, 3427, 0, 3429, + 3424, 3421, 3429, 3432, 3428, 3416, 3426, 3433, 3423, 3434, + 3421, 3427, 3437, 3423, 3424, 3435, 3436, 3426, 3428, 3431, + 3437, 3442, 3435, 3436, 3427, 3429, 3429, 3434, 3439, 3429, + 3432, 3443, 3438, 0, 3433, 3444, 3434, 3446, 3445, 3437, + 3438, 3448, 3435, 3436, 3450, 3447, 3449, 3452, 3455, 3454, + + 3439, 3454, 3449, 3442, 3447, 3439, 3448, 3444, 3443, 3438, + 3445, 3451, 3444, 3457, 3446, 3445, 3450, 3458, 3448, 3459, + 3451, 3450, 3447, 3449, 3460, 3455, 3454, 3461, 3467, 3452, + 3462, 3463, 0, 3469, 3470, 3461, 3457, 0, 3451, 3458, + 3457, 3459, 3462, 3463, 3458, 3465, 3459, 3469, 3470, 3471, + 3460, 3460, 3465, 3473, 3461, 3467, 3472, 3462, 3463, 3474, + 3469, 3470, 3476, 3471, 3481, 3475, 3477, 3478, 3480, 3479, + 3474, 3473, 3465, 3475, 3478, 3480, 3471, 3485, 3483, 3472, + 3473, 3476, 3482, 3472, 3479, 3486, 3474, 3483, 3477, 3476, + 3481, 3481, 3475, 3477, 3478, 3480, 3479, 3484, 3484, 3487, + + 3482, 3490, 3491, 3494, 3485, 3483, 3490, 3487, 3495, 3482, + 3493, 3497, 3486, 3499, 3501, 3491, 3502, 3497, 3509, 3512, + 3504, 3505, 3506, 0, 3484, 3501, 3487, 3502, 3514, 3491, + 3494, 3493, 3505, 3490, 3511, 3495, 3517, 3493, 3497, 3510, + 3499, 3501, 3504, 3502, 3506, 3509, 3510, 3504, 3505, 3506, + 3513, 3512, 3511, 3519, 3513, 3514, 3515, 3518, 0, 3519, + 3521, 3511, 3517, 3517, 3515, 3520, 3510, 3523, 3521, 3522, + 3518, 3520, 3524, 3526, 3528, 3530, 3525, 3513, 3533, 3526, + 3519, 3527, 3522, 3515, 3518, 3525, 3532, 3521, 3539, 3534, + 3527, 3523, 3520, 3532, 3523, 3540, 3522, 3537, 3524, 3524, + + 3526, 3528, 3537, 3525, 3538, 3538, 3541, 3530, 3527, 3543, + 3533, 3534, 3542, 3532, 3544, 3539, 3534, 3545, 3541, 3542, + 3546, 3547, 3540, 3549, 3537, 3550, 0, 3546, 3543, 3548, + 3544, 3538, 3550, 3541, 3551, 3545, 3543, 3548, 3549, 3542, + 3552, 3544, 3553, 0, 3545, 3554, 3555, 3546, 0, 3561, + 3549, 3556, 3550, 3547, 3557, 3543, 3548, 3554, 3562, 3563, + 3564, 3551, 3552, 3565, 3561, 3562, 3563, 3552, 3569, 3553, + 3555, 3566, 3554, 3555, 0, 3556, 3561, 3567, 3556, 3570, + 3557, 3557, 3564, 3572, 3573, 3562, 3563, 3564, 3570, 3575, + 3574, 3576, 3577, 3577, 3578, 3565, 0, 3575, 3566, 3580, + + 3569, 3567, 3577, 3584, 3567, 3572, 3570, 3587, 3583, 3581, + 3572, 3573, 3574, 3582, 3580, 3582, 3575, 3574, 3581, 3577, + 3577, 3578, 3583, 3576, 3585, 3587, 3580, 3586, 3589, 3590, + 3584, 3591, 3585, 3593, 3587, 3583, 3581, 3592, 3586, 3594, + 3582, 3595, 3596, 3597, 3598, 3600, 3593, 3599, 3603, 3601, + 0, 3585, 0, 3599, 3586, 3589, 3590, 3604, 3591, 3592, + 3593, 3594, 3598, 3601, 3592, 3607, 3594, 3610, 3595, 3596, + 3597, 3598, 3600, 3611, 3599, 3608, 3601, 3602, 3602, 3604, + 3603, 3614, 3616, 3617, 3604, 3618, 3608, 3616, 3617, 3614, + 3619, 3622, 3607, 3618, 3610, 3619, 3620, 3623, 3623, 3624, + + 3611, 3625, 3608, 3628, 3602, 3629, 3627, 3624, 3614, 3616, + 3617, 3632, 3618, 3627, 3625, 0, 3633, 3619, 3622, 3636, + 3630, 3628, 3620, 3620, 3623, 3635, 3624, 3630, 3625, 3631, + 3628, 3638, 3629, 3627, 3634, 3637, 3631, 3640, 3632, 3633, + 3635, 3634, 3637, 3633, 3641, 3643, 3640, 3630, 3642, 0, + 3649, 3636, 3635, 3643, 3638, 3642, 3631, 3644, 3638, 3645, + 3648, 3634, 3637, 3651, 3640, 3653, 3648, 3652, 3654, 3656, + 3655, 3657, 3643, 0, 0, 3642, 3641, 3649, 3653, 3644, + 3658, 3645, 3662, 0, 3644, 3655, 3645, 3648, 3656, 3652, + 3651, 3663, 3653, 3666, 3652, 3670, 3656, 3655, 3657, 3660, + + 3654, 3664, 3658, 3665, 3667, 3662, 3660, 3658, 3664, 3662, + 3665, 0, 3668, 3663, 3669, 3666, 3670, 3672, 3663, 3667, + 3666, 3673, 3670, 3669, 3678, 3674, 3660, 3668, 3664, 3673, + 3665, 3667, 3674, 3675, 3677, 3678, 3672, 3679, 3679, 3668, + 3675, 3669, 3685, 3677, 3672, 3681, 3683, 3679, 3673, 3680, + 3684, 3678, 3674, 3686, 3689, 3680, 3688, 3684, 3694, 3695, + 3675, 3677, 0, 3688, 3679, 3679, 3696, 3681, 3683, 3703, + 3690, 3706, 3681, 3683, 3685, 3686, 3680, 3684, 3689, 3700, + 3686, 3689, 3701, 3688, 3690, 3694, 3695, 3705, 3704, 3696, + 3708, 3700, 3711, 3696, 3714, 3705, 3703, 3690, 3706, 3713, + + 3713, 3727, 3708, 3716, 3701, 3718, 3700, 3715, 3715, 3701, + 3704, 3719, 3720, 3721, 3705, 3704, 3724, 3708, 3722, 3711, + 3725, 3714, 3721, 3728, 3729, 3731, 3716, 3718, 3713, 3719, + 3716, 3722, 3718, 3727, 3730, 3732, 3715, 3733, 3719, 3720, + 3721, 3734, 3730, 3724, 3735, 3722, 3737, 3725, 3734, 3738, + 3736, 3735, 3731, 3730, 3743, 3728, 3729, 3744, 3738, 3739, + 3745, 3730, 3732, 3733, 3733, 3742, 3739, 3742, 3734, 3730, + 3746, 3735, 3736, 3737, 3743, 3749, 3738, 3736, 3745, 3748, + 3744, 3743, 3746, 3750, 3744, 3751, 3739, 3745, 3748, 3752, + 0, 3753, 3742, 3754, 3755, 3756, 3757, 3746, 0, 3758, + + 3749, 3757, 3749, 3759, 3761, 3750, 3748, 3752, 3762, 3761, + 3750, 3758, 3751, 0, 0, 3770, 3752, 3753, 3753, 3766, + 3754, 3755, 3756, 3757, 3760, 3759, 3758, 3760, 3765, 3763, + 3759, 3763, 3764, 3769, 3765, 3767, 3761, 3768, 3772, 3773, + 3762, 3766, 3760, 3778, 3764, 3768, 3766, 3770, 3771, 3774, + 3775, 3760, 3780, 3782, 3760, 3765, 3763, 3767, 3779, 3764, + 3769, 3774, 3767, 3783, 3768, 3772, 3773, 3787, 3788, 3771, + 3778, 3779, 3775, 3785, 3789, 3771, 3774, 3775, 3790, 3780, + 3782, 3783, 3785, 3792, 3793, 3779, 3794, 3795, 3796, 3796, + 3783, 3798, 3799, 3804, 3787, 3788, 3802, 3803, 3809, 0, + + 3785, 3789, 0, 3802, 3803, 3790, 0, 3806, 3810, 3798, + 3792, 3793, 3811, 3794, 3795, 3796, 3804, 3805, 3798, 3799, + 3804, 3806, 3815, 3802, 3803, 3809, 3810, 3811, 3814, 3805, + 3812, 3817, 3820, 3806, 3806, 3810, 3819, 3812, 3816, 3811, + 3814, 3818, 0, 3821, 3805, 3822, 3816, 3820, 3806, 3815, + 3819, 3823, 3825, 3818, 3826, 3814, 0, 3812, 3817, 3820, + 3822, 3830, 3831, 3819, 3825, 3816, 3832, 3835, 3818, 3821, + 3821, 3831, 3822, 3833, 3833, 3834, 3835, 3838, 3823, 3825, + 3837, 3826, 0, 3830, 3839, 3845, 3840, 3841, 3830, 3831, + 3832, 3852, 3843, 3832, 3835, 3841, 3842, 3839, 3846, 3849, + + 3833, 3834, 3834, 3843, 3837, 3842, 3845, 3837, 3840, 3838, + 3865, 3839, 3845, 3840, 3841, 3850, 3846, 3852, 3852, 3843, + 3855, 3855, 3849, 3842, 3856, 3846, 3849, 3850, 3866, 3870, + 3868, 3856, 3865, 3871, 3873, 3869, 3875, 3865, 3872, 3872, + 3876, 3871, 3850, 3873, 3877, 3878, 3872, 3855, 3868, 3880, + 3875, 3856, 3866, 3869, 3870, 3866, 3870, 3868, 3884, 3883, + 3871, 3873, 3869, 3875, 3882, 3872, 3872, 3876, 3882, 3896, + 3886, 3877, 3878, 3885, 3888, 3890, 3880, 3883, 3892, 3891, + 3885, 3884, 3886, 3891, 3894, 3884, 3883, 3888, 3893, 3897, + 3895, 3882, 0, 0, 3892, 3896, 3896, 3886, 0, 3899, + + 3885, 3888, 3895, 3897, 3898, 3892, 3891, 3890, 3899, 3894, + 3893, 3894, 3898, 3900, 3903, 3893, 3897, 3895, 3901, 3904, + 3901, 3902, 3905, 3906, 3900, 3908, 3899, 3907, 3909, 3906, + 3910, 3898, 3903, 3902, 3904, 3914, 3909, 0, 3926, 3912, + 3900, 3903, 3907, 0, 3905, 3901, 3904, 3908, 3902, 3905, + 3906, 3911, 3908, 3912, 3907, 3909, 3913, 3910, 3911, 3919, + 3915, 3916, 3914, 3917, 3918, 3926, 3912, 3915, 3925, 3916, + 3913, 3918, 3924, 3928, 3927, 3925, 3929, 3932, 3911, 3931, + 3930, 3919, 3917, 3913, 3933, 3924, 3919, 3915, 3916, 0, + 3917, 3918, 3927, 3937, 3936, 3925, 3939, 3928, 3939, 3924, + + 3928, 3927, 3930, 3929, 3932, 3931, 3931, 3930, 3934, 3938, + 3935, 3933, 3940, 3941, 3942, 3937, 3934, 3935, 3936, 3943, + 3937, 3936, 3944, 3939, 3940, 3945, 3946, 3942, 3947, 3948, + 3949, 3938, 3951, 3946, 3943, 3934, 3938, 3935, 3952, 3940, + 3953, 3942, 3955, 3956, 3944, 3941, 3943, 3956, 3957, 3944, + 3958, 3959, 3945, 3946, 3961, 3947, 3948, 3949, 3960, 3951, + 3952, 3963, 3953, 3959, 3964, 3952, 3960, 3953, 3966, 3955, + 3956, 3966, 3970, 3963, 3967, 3957, 3971, 3958, 3959, 3972, + 3964, 3961, 3973, 3967, 3974, 3960, 3975, 3976, 3963, 0, + 3973, 3964, 0, 3977, 3980, 3966, 3978, 3979, 3972, 3970, + + 3976, 3967, 3971, 3971, 3978, 3982, 3972, 3977, 3997, 3973, + 3987, 3993, 0, 3988, 3976, 3990, 3974, 3993, 3975, 3979, + 3977, 3980, 3987, 3978, 3979, 3988, 3994, 3990, 3996, 3999, + 0, 4003, 3982, 3994, 3998, 3997, 4001, 3987, 3993, 4003, + 3988, 3996, 3990, 4001, 4002, 3998, 4004, 4007, 4005, 4006, + 4008, 4009, 3999, 3994, 0, 3996, 3999, 4006, 4003, 4012, + 4004, 3998, 4005, 4001, 4013, 4012, 4002, 4019, 4020, 4007, + 4013, 4002, 4008, 4004, 4007, 4005, 4006, 4008, 4009, 4014, + 4015, 4016, 4021, 4022, 4017, 4019, 4012, 4015, 4014, 4027, + 4016, 4013, 4017, 4023, 4019, 4020, 4024, 4027, 4028, 4025, + + 4026, 4032, 4033, 0, 4021, 4030, 4014, 4015, 4016, 4021, + 4031, 4017, 4030, 4034, 4035, 4022, 4027, 4031, 4024, 4023, + 4023, 4025, 4026, 4024, 4032, 4036, 4025, 4026, 4032, 4033, + 4028, 4038, 4030, 4040, 4036, 4034, 4039, 4031, 4041, 4042, + 4034, 4035, 4043, 4044, 4039, 4045, 4041, 4042, 4046, 4047, + 4048, 4044, 4036, 4040, 4038, 4050, 4052, 4053, 4038, 4045, + 4040, 4054, 0, 4039, 4054, 4041, 4042, 4055, 0, 4065, + 4044, 4059, 4045, 0, 4043, 4046, 4047, 4048, 4052, 4054, + 4060, 4050, 4050, 4052, 4053, 4056, 4058, 4057, 4054, 4055, + 4064, 4054, 4065, 4056, 4055, 4057, 4065, 4059, 4059, 4068, + + 4058, 4069, 4060, 4070, 4064, 4067, 4067, 4060, 4071, 4069, + 4074, 4072, 4056, 4058, 4057, 4075, 4073, 4064, 4074, 4076, + 4078, 4079, 4077, 4087, 0, 4068, 4068, 0, 4069, 4070, + 4070, 4080, 4067, 4072, 4071, 4071, 4073, 4074, 4072, 4081, + 4083, 0, 4075, 4073, 4077, 4078, 4076, 4078, 4079, 4077, + 4087, 4080, 4082, 4084, 4090, 4088, 4091, 4092, 4080, 4081, + 4082, 4084, 4083, 4088, 4093, 4092, 4081, 4083, 4094, 4096, + 0, 4100, 4093, 4099, 4103, 4104, 4090, 4097, 4091, 4082, + 4084, 4090, 4088, 4091, 4092, 4097, 4101, 4105, 4107, 4098, + 4110, 4093, 4113, 4114, 4094, 4094, 4096, 4098, 4100, 4099, + + 4099, 4103, 4104, 4111, 4097, 0, 4101, 4105, 0, 0, + 4107, 4111, 4110, 4101, 4105, 4107, 4098, 4110, 4112, 4113, + 4114, 0, 0, 0, 0, 0, 4112, 0, 0, 0, + 4111, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 4112, 4118, 4118, 4118, 4118, + 4118, 4118, 4118, 4119, 4119, 4119, 4119, 4119, 4119, 4119, + 4120, 4120, 4120, 4120, 4120, 4120, 4120, 4121, 4121, 4121, + 4121, 4121, 4121, 4121, 4122, 4122, 4122, 4122, 4122, 4122, + 4122, 4123, 4123, 4123, 4123, 4123, 4123, 4123, 4124, 4124, + 4124, 4124, 4124, 4124, 4124, 4126, 4126, 0, 4126, 4126, + + 4126, 4126, 4127, 4127, 0, 0, 0, 4127, 4127, 4128, + 4128, 0, 0, 4128, 0, 4128, 4129, 0, 0, 0, + 0, 0, 4129, 4130, 4130, 0, 0, 0, 4130, 4130, + 4131, 0, 0, 0, 0, 0, 4131, 4132, 4132, 0, + 4132, 4132, 4132, 4132, 4133, 0, 0, 0, 0, 0, + 4133, 4134, 4134, 0, 0, 0, 4134, 4134, 4135, 4135, + 0, 4135, 4135, 4135, 4135, 4117, 4117, 4117, 4117, 4117, + 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, + 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, + 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, + + 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, + 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, + 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, + 4117, 4117 } ; static yy_state_type yy_last_accepting_state; @@ -4495,7 +4596,7 @@ static void config_end_include(void) } #endif -#line 4496 "<stdout>" +#line 4597 "<stdout>" #define YY_NO_INPUT 1 #line 191 "util/configlexer.lex" #ifndef YY_NO_UNPUT @@ -4504,9 +4605,9 @@ static void config_end_include(void) #ifndef YY_NO_INPUT #define YY_NO_INPUT 1 #endif -#line 4505 "<stdout>" +#line 4606 "<stdout>" -#line 4507 "<stdout>" +#line 4608 "<stdout>" #define INITIAL 0 #define quotedstring 1 @@ -4730,7 +4831,7 @@ YY_DECL { #line 211 "util/configlexer.lex" -#line 4731 "<stdout>" +#line 4832 "<stdout>" while ( /*CONSTCOND*/1 ) /* loops until end-of-file is reached */ { @@ -4763,13 +4864,13 @@ yy_match: while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 4016 ) + if ( yy_current_state >= 4118 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 11459 ); + while ( yy_base[yy_current_state] != 11766 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -6090,12 +6191,12 @@ YY_RULE_SETUP case 259: YY_RULE_SETUP #line 474 "util/configlexer.lex" -{ YDVAR(1, VAR_WAIT_LIMIT_NETBLOCK) } +{ YDVAR(2, VAR_WAIT_LIMIT_NETBLOCK) } YY_BREAK case 260: YY_RULE_SETUP #line 475 "util/configlexer.lex" -{ YDVAR(1, VAR_WAIT_LIMIT_COOKIE_NETBLOCK) } +{ YDVAR(2, VAR_WAIT_LIMIT_COOKIE_NETBLOCK) } YY_BREAK case 261: YY_RULE_SETUP @@ -6560,158 +6661,203 @@ YY_RULE_SETUP case 351: YY_RULE_SETUP #line 576 "util/configlexer.lex" -{ YDVAR(1, VAR_CACHEDB_REDISPORT) } +{ YDVAR(1, VAR_CACHEDB_REDISREPLICAHOST) } YY_BREAK case 352: YY_RULE_SETUP #line 577 "util/configlexer.lex" -{ YDVAR(1, VAR_CACHEDB_REDISPATH) } +{ YDVAR(1, VAR_CACHEDB_REDISPORT) } YY_BREAK case 353: YY_RULE_SETUP #line 578 "util/configlexer.lex" -{ YDVAR(1, VAR_CACHEDB_REDISPASSWORD) } +{ YDVAR(1, VAR_CACHEDB_REDISREPLICAPORT) } YY_BREAK case 354: YY_RULE_SETUP #line 579 "util/configlexer.lex" -{ YDVAR(1, VAR_CACHEDB_REDISTIMEOUT) } +{ YDVAR(1, VAR_CACHEDB_REDISPATH) } YY_BREAK case 355: YY_RULE_SETUP #line 580 "util/configlexer.lex" -{ YDVAR(1, VAR_CACHEDB_REDISCOMMANDTIMEOUT) } +{ YDVAR(1, VAR_CACHEDB_REDISREPLICAPATH) } YY_BREAK case 356: YY_RULE_SETUP #line 581 "util/configlexer.lex" -{ YDVAR(1, VAR_CACHEDB_REDISCONNECTTIMEOUT) } +{ YDVAR(1, VAR_CACHEDB_REDISPASSWORD) } YY_BREAK case 357: YY_RULE_SETUP #line 582 "util/configlexer.lex" -{ YDVAR(1, VAR_CACHEDB_REDISEXPIRERECORDS) } +{ YDVAR(1, VAR_CACHEDB_REDISREPLICAPASSWORD) } YY_BREAK case 358: YY_RULE_SETUP #line 583 "util/configlexer.lex" -{ YDVAR(1, VAR_CACHEDB_REDISLOGICALDB) } +{ YDVAR(1, VAR_CACHEDB_REDISTIMEOUT) } YY_BREAK case 359: YY_RULE_SETUP #line 584 "util/configlexer.lex" -{ YDVAR(0, VAR_IPSET) } +{ YDVAR(1, VAR_CACHEDB_REDISREPLICATIMEOUT) } YY_BREAK case 360: YY_RULE_SETUP #line 585 "util/configlexer.lex" -{ YDVAR(1, VAR_IPSET_NAME_V4) } +{ YDVAR(1, VAR_CACHEDB_REDISCOMMANDTIMEOUT) } YY_BREAK case 361: YY_RULE_SETUP #line 586 "util/configlexer.lex" -{ YDVAR(1, VAR_IPSET_NAME_V6) } +{ YDVAR(1, VAR_CACHEDB_REDISREPLICACOMMANDTIMEOUT) } YY_BREAK case 362: YY_RULE_SETUP #line 587 "util/configlexer.lex" -{ YDVAR(1, VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM) } +{ YDVAR(1, VAR_CACHEDB_REDISCONNECTTIMEOUT) } YY_BREAK case 363: YY_RULE_SETUP #line 588 "util/configlexer.lex" -{ YDVAR(2, VAR_TCP_CONNECTION_LIMIT) } +{ YDVAR(1, VAR_CACHEDB_REDISREPLICACONNECTTIMEOUT) } YY_BREAK case 364: YY_RULE_SETUP #line 589 "util/configlexer.lex" -{ YDVAR(1, VAR_ANSWER_COOKIE ) } +{ YDVAR(1, VAR_CACHEDB_REDISEXPIRERECORDS) } YY_BREAK case 365: YY_RULE_SETUP #line 590 "util/configlexer.lex" -{ YDVAR(1, VAR_COOKIE_SECRET) } +{ YDVAR(1, VAR_CACHEDB_REDISLOGICALDB) } YY_BREAK case 366: YY_RULE_SETUP #line 591 "util/configlexer.lex" -{ YDVAR(1, VAR_COOKIE_SECRET_FILE) } +{ YDVAR(1, VAR_CACHEDB_REDISREPLICALOGICALDB) } YY_BREAK case 367: YY_RULE_SETUP #line 592 "util/configlexer.lex" -{ YDVAR(2, VAR_EDNS_CLIENT_STRING) } +{ YDVAR(0, VAR_IPSET) } YY_BREAK case 368: YY_RULE_SETUP #line 593 "util/configlexer.lex" -{ YDVAR(1, VAR_EDNS_CLIENT_STRING_OPCODE) } +{ YDVAR(1, VAR_IPSET_NAME_V4) } YY_BREAK case 369: YY_RULE_SETUP #line 594 "util/configlexer.lex" -{ YDVAR(1, VAR_NSID ) } +{ YDVAR(1, VAR_IPSET_NAME_V6) } YY_BREAK case 370: YY_RULE_SETUP #line 595 "util/configlexer.lex" -{ YDVAR(1, VAR_EDE ) } +{ YDVAR(1, VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM) } YY_BREAK case 371: YY_RULE_SETUP #line 596 "util/configlexer.lex" -{ YDVAR(1, VAR_PROXY_PROTOCOL_PORT) } +{ YDVAR(2, VAR_TCP_CONNECTION_LIMIT) } YY_BREAK case 372: YY_RULE_SETUP #line 597 "util/configlexer.lex" -{ YDVAR(1, VAR_ITER_SCRUB_NS) } +{ YDVAR(1, VAR_ANSWER_COOKIE ) } YY_BREAK case 373: YY_RULE_SETUP #line 598 "util/configlexer.lex" -{ YDVAR(1, VAR_ITER_SCRUB_CNAME) } +{ YDVAR(1, VAR_COOKIE_SECRET) } YY_BREAK case 374: YY_RULE_SETUP #line 599 "util/configlexer.lex" -{ YDVAR(1, VAR_MAX_GLOBAL_QUOTA) } +{ YDVAR(1, VAR_COOKIE_SECRET_FILE) } YY_BREAK case 375: -/* rule 375 can match eol */ YY_RULE_SETUP #line 600 "util/configlexer.lex" -{ LEXOUT(("NL\n")); cfg_parser->line++; } +{ YDVAR(2, VAR_EDNS_CLIENT_STRING) } YY_BREAK -/* Quoted strings. Strip leading and ending quotes */ case 376: YY_RULE_SETUP +#line 601 "util/configlexer.lex" +{ YDVAR(1, VAR_EDNS_CLIENT_STRING_OPCODE) } + YY_BREAK +case 377: +YY_RULE_SETUP +#line 602 "util/configlexer.lex" +{ YDVAR(1, VAR_NSID ) } + YY_BREAK +case 378: +YY_RULE_SETUP #line 603 "util/configlexer.lex" +{ YDVAR(1, VAR_EDE ) } + YY_BREAK +case 379: +YY_RULE_SETUP +#line 604 "util/configlexer.lex" +{ YDVAR(1, VAR_DNS_ERROR_REPORTING ) } + YY_BREAK +case 380: +YY_RULE_SETUP +#line 605 "util/configlexer.lex" +{ YDVAR(1, VAR_PROXY_PROTOCOL_PORT) } + YY_BREAK +case 381: +YY_RULE_SETUP +#line 606 "util/configlexer.lex" +{ YDVAR(1, VAR_ITER_SCRUB_NS) } + YY_BREAK +case 382: +YY_RULE_SETUP +#line 607 "util/configlexer.lex" +{ YDVAR(1, VAR_ITER_SCRUB_CNAME) } + YY_BREAK +case 383: +YY_RULE_SETUP +#line 608 "util/configlexer.lex" +{ YDVAR(1, VAR_MAX_GLOBAL_QUOTA) } + YY_BREAK +case 384: +/* rule 384 can match eol */ +YY_RULE_SETUP +#line 609 "util/configlexer.lex" +{ LEXOUT(("NL\n")); cfg_parser->line++; } + YY_BREAK +/* Quoted strings. Strip leading and ending quotes */ +case 385: +YY_RULE_SETUP +#line 612 "util/configlexer.lex" { BEGIN(quotedstring); LEXOUT(("QS ")); } YY_BREAK case YY_STATE_EOF(quotedstring): -#line 604 "util/configlexer.lex" +#line 613 "util/configlexer.lex" { yyerror("EOF inside quoted string"); if(--num_args == 0) { BEGIN(INITIAL); } else { BEGIN(val); } } YY_BREAK -case 377: +case 386: YY_RULE_SETUP -#line 609 "util/configlexer.lex" +#line 618 "util/configlexer.lex" { LEXOUT(("STR(%s) ", yytext)); yymore(); } YY_BREAK -case 378: -/* rule 378 can match eol */ +case 387: +/* rule 387 can match eol */ YY_RULE_SETUP -#line 610 "util/configlexer.lex" +#line 619 "util/configlexer.lex" { yyerror("newline inside quoted string, no end \""); cfg_parser->line++; BEGIN(INITIAL); } YY_BREAK -case 379: +case 388: YY_RULE_SETUP -#line 612 "util/configlexer.lex" +#line 621 "util/configlexer.lex" { LEXOUT(("QE ")); if(--num_args == 0) { BEGIN(INITIAL); } @@ -6724,34 +6870,34 @@ YY_RULE_SETUP } YY_BREAK /* Single Quoted strings. Strip leading and ending quotes */ -case 380: +case 389: YY_RULE_SETUP -#line 624 "util/configlexer.lex" +#line 633 "util/configlexer.lex" { BEGIN(singlequotedstr); LEXOUT(("SQS ")); } YY_BREAK case YY_STATE_EOF(singlequotedstr): -#line 625 "util/configlexer.lex" +#line 634 "util/configlexer.lex" { yyerror("EOF inside quoted string"); if(--num_args == 0) { BEGIN(INITIAL); } else { BEGIN(val); } } YY_BREAK -case 381: +case 390: YY_RULE_SETUP -#line 630 "util/configlexer.lex" +#line 639 "util/configlexer.lex" { LEXOUT(("STR(%s) ", yytext)); yymore(); } YY_BREAK -case 382: -/* rule 382 can match eol */ +case 391: +/* rule 391 can match eol */ YY_RULE_SETUP -#line 631 "util/configlexer.lex" +#line 640 "util/configlexer.lex" { yyerror("newline inside quoted string, no end '"); cfg_parser->line++; BEGIN(INITIAL); } YY_BREAK -case 383: +case 392: YY_RULE_SETUP -#line 633 "util/configlexer.lex" +#line 642 "util/configlexer.lex" { LEXOUT(("SQE ")); if(--num_args == 0) { BEGIN(INITIAL); } @@ -6764,38 +6910,38 @@ YY_RULE_SETUP } YY_BREAK /* include: directive */ -case 384: +case 393: YY_RULE_SETUP -#line 645 "util/configlexer.lex" +#line 654 "util/configlexer.lex" { LEXOUT(("v(%s) ", yytext)); inc_prev = YYSTATE; BEGIN(include); } YY_BREAK case YY_STATE_EOF(include): -#line 647 "util/configlexer.lex" +#line 656 "util/configlexer.lex" { yyerror("EOF inside include directive"); BEGIN(inc_prev); } YY_BREAK -case 385: +case 394: YY_RULE_SETUP -#line 651 "util/configlexer.lex" +#line 660 "util/configlexer.lex" { LEXOUT(("ISP ")); /* ignore */ } YY_BREAK -case 386: -/* rule 386 can match eol */ +case 395: +/* rule 395 can match eol */ YY_RULE_SETUP -#line 652 "util/configlexer.lex" +#line 661 "util/configlexer.lex" { LEXOUT(("NL\n")); cfg_parser->line++;} YY_BREAK -case 387: +case 396: YY_RULE_SETUP -#line 653 "util/configlexer.lex" +#line 662 "util/configlexer.lex" { LEXOUT(("IQS ")); BEGIN(include_quoted); } YY_BREAK -case 388: +case 397: YY_RULE_SETUP -#line 654 "util/configlexer.lex" +#line 663 "util/configlexer.lex" { LEXOUT(("Iunquotedstr(%s) ", yytext)); config_start_include_glob(yytext, 0); @@ -6803,27 +6949,27 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(include_quoted): -#line 659 "util/configlexer.lex" +#line 668 "util/configlexer.lex" { yyerror("EOF inside quoted string"); BEGIN(inc_prev); } YY_BREAK -case 389: +case 398: YY_RULE_SETUP -#line 663 "util/configlexer.lex" +#line 672 "util/configlexer.lex" { LEXOUT(("ISTR(%s) ", yytext)); yymore(); } YY_BREAK -case 390: -/* rule 390 can match eol */ +case 399: +/* rule 399 can match eol */ YY_RULE_SETUP -#line 664 "util/configlexer.lex" +#line 673 "util/configlexer.lex" { yyerror("newline before \" in include name"); cfg_parser->line++; BEGIN(inc_prev); } YY_BREAK -case 391: +case 400: YY_RULE_SETUP -#line 666 "util/configlexer.lex" +#line 675 "util/configlexer.lex" { LEXOUT(("IQE ")); yytext[yyleng - 1] = '\0'; @@ -6833,7 +6979,7 @@ YY_RULE_SETUP YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(val): -#line 672 "util/configlexer.lex" +#line 681 "util/configlexer.lex" { LEXOUT(("LEXEOF ")); yy_set_bol(1); /* Set beginning of line, so "^" rules match. */ @@ -6848,39 +6994,39 @@ case YY_STATE_EOF(val): } YY_BREAK /* include-toplevel: directive */ -case 392: +case 401: YY_RULE_SETUP -#line 686 "util/configlexer.lex" +#line 695 "util/configlexer.lex" { LEXOUT(("v(%s) ", yytext)); inc_prev = YYSTATE; BEGIN(include_toplevel); } YY_BREAK case YY_STATE_EOF(include_toplevel): -#line 689 "util/configlexer.lex" +#line 698 "util/configlexer.lex" { yyerror("EOF inside include_toplevel directive"); BEGIN(inc_prev); } YY_BREAK -case 393: +case 402: YY_RULE_SETUP -#line 693 "util/configlexer.lex" +#line 702 "util/configlexer.lex" { LEXOUT(("ITSP ")); /* ignore */ } YY_BREAK -case 394: -/* rule 394 can match eol */ +case 403: +/* rule 403 can match eol */ YY_RULE_SETUP -#line 694 "util/configlexer.lex" +#line 703 "util/configlexer.lex" { LEXOUT(("NL\n")); cfg_parser->line++; } YY_BREAK -case 395: +case 404: YY_RULE_SETUP -#line 695 "util/configlexer.lex" +#line 704 "util/configlexer.lex" { LEXOUT(("ITQS ")); BEGIN(include_toplevel_quoted); } YY_BREAK -case 396: +case 405: YY_RULE_SETUP -#line 696 "util/configlexer.lex" +#line 705 "util/configlexer.lex" { LEXOUT(("ITunquotedstr(%s) ", yytext)); config_start_include_glob(yytext, 1); @@ -6889,29 +7035,29 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(include_toplevel_quoted): -#line 702 "util/configlexer.lex" +#line 711 "util/configlexer.lex" { yyerror("EOF inside quoted string"); BEGIN(inc_prev); } YY_BREAK -case 397: +case 406: YY_RULE_SETUP -#line 706 "util/configlexer.lex" +#line 715 "util/configlexer.lex" { LEXOUT(("ITSTR(%s) ", yytext)); yymore(); } YY_BREAK -case 398: -/* rule 398 can match eol */ +case 407: +/* rule 407 can match eol */ YY_RULE_SETUP -#line 707 "util/configlexer.lex" +#line 716 "util/configlexer.lex" { yyerror("newline before \" in include name"); cfg_parser->line++; BEGIN(inc_prev); } YY_BREAK -case 399: +case 408: YY_RULE_SETUP -#line 711 "util/configlexer.lex" +#line 720 "util/configlexer.lex" { LEXOUT(("ITQE ")); yytext[yyleng - 1] = '\0'; @@ -6920,33 +7066,33 @@ YY_RULE_SETUP return (VAR_FORCE_TOPLEVEL); } YY_BREAK -case 400: +case 409: YY_RULE_SETUP -#line 719 "util/configlexer.lex" +#line 728 "util/configlexer.lex" { LEXOUT(("unquotedstr(%s) ", yytext)); if(--num_args == 0) { BEGIN(INITIAL); } yylval.str = strdup(yytext); return STRING_ARG; } YY_BREAK -case 401: +case 410: YY_RULE_SETUP -#line 723 "util/configlexer.lex" +#line 732 "util/configlexer.lex" { ub_c_error_msg("unknown keyword '%s'", yytext); } YY_BREAK -case 402: +case 411: YY_RULE_SETUP -#line 727 "util/configlexer.lex" +#line 736 "util/configlexer.lex" { ub_c_error_msg("stray '%s'", yytext); } YY_BREAK -case 403: +case 412: YY_RULE_SETUP -#line 731 "util/configlexer.lex" +#line 740 "util/configlexer.lex" ECHO; YY_BREAK -#line 6947 "<stdout>" +#line 7093 "<stdout>" case YY_END_OF_BUFFER: { @@ -7241,7 +7387,7 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 4016 ) + if ( yy_current_state >= 4118 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; @@ -7269,11 +7415,11 @@ static int yy_get_next_buffer (void) while ( yy_chk[yy_base[yy_current_state] + yy_c] != yy_current_state ) { yy_current_state = (int) yy_def[yy_current_state]; - if ( yy_current_state >= 4016 ) + if ( yy_current_state >= 4118 ) yy_c = yy_meta[yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + yy_c]; - yy_is_jam = (yy_current_state == 4015); + yy_is_jam = (yy_current_state == 4117); return yy_is_jam ? 0 : yy_current_state; } @@ -7912,6 +8058,6 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 731 "util/configlexer.lex" +#line 740 "util/configlexer.lex" diff --git a/util/configlexer.lex b/util/configlexer.lex index 4c0416f734df..bc258673d712 100644 --- a/util/configlexer.lex +++ b/util/configlexer.lex @@ -471,8 +471,8 @@ unknown-server-time-limit{COLON} { YDVAR(1, VAR_UNKNOWN_SERVER_TIME_LIMIT) } discard-timeout{COLON} { YDVAR(1, VAR_DISCARD_TIMEOUT) } wait-limit{COLON} { YDVAR(1, VAR_WAIT_LIMIT) } wait-limit-cookie{COLON} { YDVAR(1, VAR_WAIT_LIMIT_COOKIE) } -wait-limit-netblock{COLON} { YDVAR(1, VAR_WAIT_LIMIT_NETBLOCK) } -wait-limit-cookie-netblock{COLON} { YDVAR(1, VAR_WAIT_LIMIT_COOKIE_NETBLOCK) } +wait-limit-netblock{COLON} { YDVAR(2, VAR_WAIT_LIMIT_NETBLOCK) } +wait-limit-cookie-netblock{COLON} { YDVAR(2, VAR_WAIT_LIMIT_COOKIE_NETBLOCK) } max-udp-size{COLON} { YDVAR(1, VAR_MAX_UDP_SIZE) } dns64-prefix{COLON} { YDVAR(1, VAR_DNS64_PREFIX) } dns64-synthall{COLON} { YDVAR(1, VAR_DNS64_SYNTHALL) } @@ -572,15 +572,23 @@ backend{COLON} { YDVAR(1, VAR_CACHEDB_BACKEND) } secret-seed{COLON} { YDVAR(1, VAR_CACHEDB_SECRETSEED) } cachedb-no-store{COLON} { YDVAR(1, VAR_CACHEDB_NO_STORE) } cachedb-check-when-serve-expired{COLON} { YDVAR(1, VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED) } -redis-server-host{COLON} { YDVAR(1, VAR_CACHEDB_REDISHOST) } -redis-server-port{COLON} { YDVAR(1, VAR_CACHEDB_REDISPORT) } -redis-server-path{COLON} { YDVAR(1, VAR_CACHEDB_REDISPATH) } -redis-server-password{COLON} { YDVAR(1, VAR_CACHEDB_REDISPASSWORD) } -redis-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISTIMEOUT) } +redis-server-host{COLON} { YDVAR(1, VAR_CACHEDB_REDISHOST) } +redis-replica-server-host{COLON} { YDVAR(1, VAR_CACHEDB_REDISREPLICAHOST) } +redis-server-port{COLON} { YDVAR(1, VAR_CACHEDB_REDISPORT) } +redis-replica-server-port{COLON} { YDVAR(1, VAR_CACHEDB_REDISREPLICAPORT) } +redis-server-path{COLON} { YDVAR(1, VAR_CACHEDB_REDISPATH) } +redis-replica-server-path{COLON} { YDVAR(1, VAR_CACHEDB_REDISREPLICAPATH) } +redis-server-password{COLON} { YDVAR(1, VAR_CACHEDB_REDISPASSWORD) } +redis-replica-server-password{COLON} { YDVAR(1, VAR_CACHEDB_REDISREPLICAPASSWORD) } +redis-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISTIMEOUT) } +redis-replica-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISREPLICATIMEOUT) } redis-command-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISCOMMANDTIMEOUT) } +redis-replica-command-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISREPLICACOMMANDTIMEOUT) } redis-connect-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISCONNECTTIMEOUT) } +redis-replica-connect-timeout{COLON} { YDVAR(1, VAR_CACHEDB_REDISREPLICACONNECTTIMEOUT) } redis-expire-records{COLON} { YDVAR(1, VAR_CACHEDB_REDISEXPIRERECORDS) } -redis-logical-db{COLON} { YDVAR(1, VAR_CACHEDB_REDISLOGICALDB) } +redis-logical-db{COLON} { YDVAR(1, VAR_CACHEDB_REDISLOGICALDB) } +redis-replica-logical-db{COLON} { YDVAR(1, VAR_CACHEDB_REDISREPLICALOGICALDB) } ipset{COLON} { YDVAR(0, VAR_IPSET) } name-v4{COLON} { YDVAR(1, VAR_IPSET_NAME_V4) } name-v6{COLON} { YDVAR(1, VAR_IPSET_NAME_V6) } @@ -593,6 +601,7 @@ edns-client-string{COLON} { YDVAR(2, VAR_EDNS_CLIENT_STRING) } edns-client-string-opcode{COLON} { YDVAR(1, VAR_EDNS_CLIENT_STRING_OPCODE) } nsid{COLON} { YDVAR(1, VAR_NSID ) } ede{COLON} { YDVAR(1, VAR_EDE ) } +dns-error-reporting{COLON} { YDVAR(1, VAR_DNS_ERROR_REPORTING ) } proxy-protocol-port{COLON} { YDVAR(1, VAR_PROXY_PROTOCOL_PORT) } iter-scrub-ns{COLON} { YDVAR(1, VAR_ITER_SCRUB_NS) } iter-scrub-cname{COLON} { YDVAR(1, VAR_ITER_SCRUB_CNAME) } diff --git a/util/configparser.c b/util/configparser.c index 62a6775e55de..10eb29579c41 100644 --- a/util/configparser.c +++ b/util/configparser.c @@ -411,485 +411,503 @@ enum yysymbol_kind_t YYSYMBOL_VAR_CACHEDB_BACKEND = 282, /* VAR_CACHEDB_BACKEND */ YYSYMBOL_VAR_CACHEDB_SECRETSEED = 283, /* VAR_CACHEDB_SECRETSEED */ YYSYMBOL_VAR_CACHEDB_REDISHOST = 284, /* VAR_CACHEDB_REDISHOST */ - YYSYMBOL_VAR_CACHEDB_REDISPORT = 285, /* VAR_CACHEDB_REDISPORT */ - YYSYMBOL_VAR_CACHEDB_REDISTIMEOUT = 286, /* VAR_CACHEDB_REDISTIMEOUT */ - YYSYMBOL_VAR_CACHEDB_REDISEXPIRERECORDS = 287, /* VAR_CACHEDB_REDISEXPIRERECORDS */ - YYSYMBOL_VAR_CACHEDB_REDISPATH = 288, /* VAR_CACHEDB_REDISPATH */ - YYSYMBOL_VAR_CACHEDB_REDISPASSWORD = 289, /* VAR_CACHEDB_REDISPASSWORD */ - YYSYMBOL_VAR_CACHEDB_REDISLOGICALDB = 290, /* VAR_CACHEDB_REDISLOGICALDB */ - YYSYMBOL_VAR_CACHEDB_REDISCOMMANDTIMEOUT = 291, /* VAR_CACHEDB_REDISCOMMANDTIMEOUT */ - YYSYMBOL_VAR_CACHEDB_REDISCONNECTTIMEOUT = 292, /* VAR_CACHEDB_REDISCONNECTTIMEOUT */ - YYSYMBOL_VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 293, /* VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM */ - YYSYMBOL_VAR_FOR_UPSTREAM = 294, /* VAR_FOR_UPSTREAM */ - YYSYMBOL_VAR_AUTH_ZONE = 295, /* VAR_AUTH_ZONE */ - YYSYMBOL_VAR_ZONEFILE = 296, /* VAR_ZONEFILE */ - YYSYMBOL_VAR_MASTER = 297, /* VAR_MASTER */ - YYSYMBOL_VAR_URL = 298, /* VAR_URL */ - YYSYMBOL_VAR_FOR_DOWNSTREAM = 299, /* VAR_FOR_DOWNSTREAM */ - YYSYMBOL_VAR_FALLBACK_ENABLED = 300, /* VAR_FALLBACK_ENABLED */ - YYSYMBOL_VAR_TLS_ADDITIONAL_PORT = 301, /* VAR_TLS_ADDITIONAL_PORT */ - YYSYMBOL_VAR_LOW_RTT = 302, /* VAR_LOW_RTT */ - YYSYMBOL_VAR_LOW_RTT_PERMIL = 303, /* VAR_LOW_RTT_PERMIL */ - YYSYMBOL_VAR_FAST_SERVER_PERMIL = 304, /* VAR_FAST_SERVER_PERMIL */ - YYSYMBOL_VAR_FAST_SERVER_NUM = 305, /* VAR_FAST_SERVER_NUM */ - YYSYMBOL_VAR_ALLOW_NOTIFY = 306, /* VAR_ALLOW_NOTIFY */ - YYSYMBOL_VAR_TLS_WIN_CERT = 307, /* VAR_TLS_WIN_CERT */ - YYSYMBOL_VAR_TCP_CONNECTION_LIMIT = 308, /* VAR_TCP_CONNECTION_LIMIT */ - YYSYMBOL_VAR_ANSWER_COOKIE = 309, /* VAR_ANSWER_COOKIE */ - YYSYMBOL_VAR_COOKIE_SECRET = 310, /* VAR_COOKIE_SECRET */ - YYSYMBOL_VAR_IP_RATELIMIT_COOKIE = 311, /* VAR_IP_RATELIMIT_COOKIE */ - YYSYMBOL_VAR_FORWARD_NO_CACHE = 312, /* VAR_FORWARD_NO_CACHE */ - YYSYMBOL_VAR_STUB_NO_CACHE = 313, /* VAR_STUB_NO_CACHE */ - YYSYMBOL_VAR_LOG_SERVFAIL = 314, /* VAR_LOG_SERVFAIL */ - YYSYMBOL_VAR_DENY_ANY = 315, /* VAR_DENY_ANY */ - YYSYMBOL_VAR_UNKNOWN_SERVER_TIME_LIMIT = 316, /* VAR_UNKNOWN_SERVER_TIME_LIMIT */ - YYSYMBOL_VAR_LOG_TAG_QUERYREPLY = 317, /* VAR_LOG_TAG_QUERYREPLY */ - YYSYMBOL_VAR_DISCARD_TIMEOUT = 318, /* VAR_DISCARD_TIMEOUT */ - YYSYMBOL_VAR_WAIT_LIMIT = 319, /* VAR_WAIT_LIMIT */ - YYSYMBOL_VAR_WAIT_LIMIT_COOKIE = 320, /* VAR_WAIT_LIMIT_COOKIE */ - YYSYMBOL_VAR_WAIT_LIMIT_NETBLOCK = 321, /* VAR_WAIT_LIMIT_NETBLOCK */ - YYSYMBOL_VAR_WAIT_LIMIT_COOKIE_NETBLOCK = 322, /* VAR_WAIT_LIMIT_COOKIE_NETBLOCK */ - YYSYMBOL_VAR_STREAM_WAIT_SIZE = 323, /* VAR_STREAM_WAIT_SIZE */ - YYSYMBOL_VAR_TLS_CIPHERS = 324, /* VAR_TLS_CIPHERS */ - YYSYMBOL_VAR_TLS_CIPHERSUITES = 325, /* VAR_TLS_CIPHERSUITES */ - YYSYMBOL_VAR_TLS_USE_SNI = 326, /* VAR_TLS_USE_SNI */ - YYSYMBOL_VAR_IPSET = 327, /* VAR_IPSET */ - YYSYMBOL_VAR_IPSET_NAME_V4 = 328, /* VAR_IPSET_NAME_V4 */ - YYSYMBOL_VAR_IPSET_NAME_V6 = 329, /* VAR_IPSET_NAME_V6 */ - YYSYMBOL_VAR_TLS_SESSION_TICKET_KEYS = 330, /* VAR_TLS_SESSION_TICKET_KEYS */ - YYSYMBOL_VAR_RPZ = 331, /* VAR_RPZ */ - YYSYMBOL_VAR_TAGS = 332, /* VAR_TAGS */ - YYSYMBOL_VAR_RPZ_ACTION_OVERRIDE = 333, /* VAR_RPZ_ACTION_OVERRIDE */ - YYSYMBOL_VAR_RPZ_CNAME_OVERRIDE = 334, /* VAR_RPZ_CNAME_OVERRIDE */ - YYSYMBOL_VAR_RPZ_LOG = 335, /* VAR_RPZ_LOG */ - YYSYMBOL_VAR_RPZ_LOG_NAME = 336, /* VAR_RPZ_LOG_NAME */ - YYSYMBOL_VAR_DYNLIB = 337, /* VAR_DYNLIB */ - YYSYMBOL_VAR_DYNLIB_FILE = 338, /* VAR_DYNLIB_FILE */ - YYSYMBOL_VAR_EDNS_CLIENT_STRING = 339, /* VAR_EDNS_CLIENT_STRING */ - YYSYMBOL_VAR_EDNS_CLIENT_STRING_OPCODE = 340, /* VAR_EDNS_CLIENT_STRING_OPCODE */ - YYSYMBOL_VAR_NSID = 341, /* VAR_NSID */ - YYSYMBOL_VAR_ZONEMD_PERMISSIVE_MODE = 342, /* VAR_ZONEMD_PERMISSIVE_MODE */ - YYSYMBOL_VAR_ZONEMD_CHECK = 343, /* VAR_ZONEMD_CHECK */ - YYSYMBOL_VAR_ZONEMD_REJECT_ABSENCE = 344, /* VAR_ZONEMD_REJECT_ABSENCE */ - YYSYMBOL_VAR_RPZ_SIGNAL_NXDOMAIN_RA = 345, /* VAR_RPZ_SIGNAL_NXDOMAIN_RA */ - YYSYMBOL_VAR_INTERFACE_AUTOMATIC_PORTS = 346, /* VAR_INTERFACE_AUTOMATIC_PORTS */ - YYSYMBOL_VAR_EDE = 347, /* VAR_EDE */ - YYSYMBOL_VAR_INTERFACE_ACTION = 348, /* VAR_INTERFACE_ACTION */ - YYSYMBOL_VAR_INTERFACE_VIEW = 349, /* VAR_INTERFACE_VIEW */ - YYSYMBOL_VAR_INTERFACE_TAG = 350, /* VAR_INTERFACE_TAG */ - YYSYMBOL_VAR_INTERFACE_TAG_ACTION = 351, /* VAR_INTERFACE_TAG_ACTION */ - YYSYMBOL_VAR_INTERFACE_TAG_DATA = 352, /* VAR_INTERFACE_TAG_DATA */ - YYSYMBOL_VAR_QUIC_PORT = 353, /* VAR_QUIC_PORT */ - YYSYMBOL_VAR_QUIC_SIZE = 354, /* VAR_QUIC_SIZE */ - YYSYMBOL_VAR_PROXY_PROTOCOL_PORT = 355, /* VAR_PROXY_PROTOCOL_PORT */ - YYSYMBOL_VAR_STATISTICS_INHIBIT_ZERO = 356, /* VAR_STATISTICS_INHIBIT_ZERO */ - YYSYMBOL_VAR_HARDEN_UNKNOWN_ADDITIONAL = 357, /* VAR_HARDEN_UNKNOWN_ADDITIONAL */ - YYSYMBOL_VAR_DISABLE_EDNS_DO = 358, /* VAR_DISABLE_EDNS_DO */ - YYSYMBOL_VAR_CACHEDB_NO_STORE = 359, /* VAR_CACHEDB_NO_STORE */ - YYSYMBOL_VAR_LOG_DESTADDR = 360, /* VAR_LOG_DESTADDR */ - YYSYMBOL_VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED = 361, /* VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED */ - YYSYMBOL_VAR_COOKIE_SECRET_FILE = 362, /* VAR_COOKIE_SECRET_FILE */ - YYSYMBOL_VAR_ITER_SCRUB_NS = 363, /* VAR_ITER_SCRUB_NS */ - YYSYMBOL_VAR_ITER_SCRUB_CNAME = 364, /* VAR_ITER_SCRUB_CNAME */ - YYSYMBOL_VAR_MAX_GLOBAL_QUOTA = 365, /* VAR_MAX_GLOBAL_QUOTA */ - YYSYMBOL_VAR_HARDEN_UNVERIFIED_GLUE = 366, /* VAR_HARDEN_UNVERIFIED_GLUE */ - YYSYMBOL_VAR_LOG_TIME_ISO = 367, /* VAR_LOG_TIME_ISO */ - YYSYMBOL_YYACCEPT = 368, /* $accept */ - YYSYMBOL_toplevelvars = 369, /* toplevelvars */ - YYSYMBOL_toplevelvar = 370, /* toplevelvar */ - YYSYMBOL_force_toplevel = 371, /* force_toplevel */ - YYSYMBOL_serverstart = 372, /* serverstart */ - YYSYMBOL_contents_server = 373, /* contents_server */ - YYSYMBOL_content_server = 374, /* content_server */ - YYSYMBOL_stub_clause = 375, /* stub_clause */ - YYSYMBOL_stubstart = 376, /* stubstart */ - YYSYMBOL_contents_stub = 377, /* contents_stub */ - YYSYMBOL_content_stub = 378, /* content_stub */ - YYSYMBOL_forward_clause = 379, /* forward_clause */ - YYSYMBOL_forwardstart = 380, /* forwardstart */ - YYSYMBOL_contents_forward = 381, /* contents_forward */ - YYSYMBOL_content_forward = 382, /* content_forward */ - YYSYMBOL_view_clause = 383, /* view_clause */ - YYSYMBOL_viewstart = 384, /* viewstart */ - YYSYMBOL_contents_view = 385, /* contents_view */ - YYSYMBOL_content_view = 386, /* content_view */ - YYSYMBOL_authstart = 387, /* authstart */ - YYSYMBOL_contents_auth = 388, /* contents_auth */ - YYSYMBOL_content_auth = 389, /* content_auth */ - YYSYMBOL_rpz_tag = 390, /* rpz_tag */ - YYSYMBOL_rpz_action_override = 391, /* rpz_action_override */ - YYSYMBOL_rpz_cname_override = 392, /* rpz_cname_override */ - YYSYMBOL_rpz_log = 393, /* rpz_log */ - YYSYMBOL_rpz_log_name = 394, /* rpz_log_name */ - YYSYMBOL_rpz_signal_nxdomain_ra = 395, /* rpz_signal_nxdomain_ra */ - YYSYMBOL_rpzstart = 396, /* rpzstart */ - YYSYMBOL_contents_rpz = 397, /* contents_rpz */ - YYSYMBOL_content_rpz = 398, /* content_rpz */ - YYSYMBOL_server_num_threads = 399, /* server_num_threads */ - YYSYMBOL_server_verbosity = 400, /* server_verbosity */ - YYSYMBOL_server_statistics_interval = 401, /* server_statistics_interval */ - YYSYMBOL_server_statistics_cumulative = 402, /* server_statistics_cumulative */ - YYSYMBOL_server_extended_statistics = 403, /* server_extended_statistics */ - YYSYMBOL_server_statistics_inhibit_zero = 404, /* server_statistics_inhibit_zero */ - YYSYMBOL_server_shm_enable = 405, /* server_shm_enable */ - YYSYMBOL_server_shm_key = 406, /* server_shm_key */ - YYSYMBOL_server_port = 407, /* server_port */ - YYSYMBOL_server_send_client_subnet = 408, /* server_send_client_subnet */ - YYSYMBOL_server_client_subnet_zone = 409, /* server_client_subnet_zone */ - YYSYMBOL_server_client_subnet_always_forward = 410, /* server_client_subnet_always_forward */ - YYSYMBOL_server_client_subnet_opcode = 411, /* server_client_subnet_opcode */ - YYSYMBOL_server_max_client_subnet_ipv4 = 412, /* server_max_client_subnet_ipv4 */ - YYSYMBOL_server_max_client_subnet_ipv6 = 413, /* server_max_client_subnet_ipv6 */ - YYSYMBOL_server_min_client_subnet_ipv4 = 414, /* server_min_client_subnet_ipv4 */ - YYSYMBOL_server_min_client_subnet_ipv6 = 415, /* server_min_client_subnet_ipv6 */ - YYSYMBOL_server_max_ecs_tree_size_ipv4 = 416, /* server_max_ecs_tree_size_ipv4 */ - YYSYMBOL_server_max_ecs_tree_size_ipv6 = 417, /* server_max_ecs_tree_size_ipv6 */ - YYSYMBOL_server_interface = 418, /* server_interface */ - YYSYMBOL_server_outgoing_interface = 419, /* server_outgoing_interface */ - YYSYMBOL_server_outgoing_range = 420, /* server_outgoing_range */ - YYSYMBOL_server_outgoing_port_permit = 421, /* server_outgoing_port_permit */ - YYSYMBOL_server_outgoing_port_avoid = 422, /* server_outgoing_port_avoid */ - YYSYMBOL_server_outgoing_num_tcp = 423, /* server_outgoing_num_tcp */ - YYSYMBOL_server_incoming_num_tcp = 424, /* server_incoming_num_tcp */ - YYSYMBOL_server_interface_automatic = 425, /* server_interface_automatic */ - YYSYMBOL_server_interface_automatic_ports = 426, /* server_interface_automatic_ports */ - YYSYMBOL_server_do_ip4 = 427, /* server_do_ip4 */ - YYSYMBOL_server_do_ip6 = 428, /* server_do_ip6 */ - YYSYMBOL_server_do_nat64 = 429, /* server_do_nat64 */ - YYSYMBOL_server_do_udp = 430, /* server_do_udp */ - YYSYMBOL_server_do_tcp = 431, /* server_do_tcp */ - YYSYMBOL_server_prefer_ip4 = 432, /* server_prefer_ip4 */ - YYSYMBOL_server_prefer_ip6 = 433, /* server_prefer_ip6 */ - YYSYMBOL_server_tcp_mss = 434, /* server_tcp_mss */ - YYSYMBOL_server_outgoing_tcp_mss = 435, /* server_outgoing_tcp_mss */ - YYSYMBOL_server_tcp_idle_timeout = 436, /* server_tcp_idle_timeout */ - YYSYMBOL_server_max_reuse_tcp_queries = 437, /* server_max_reuse_tcp_queries */ - YYSYMBOL_server_tcp_reuse_timeout = 438, /* server_tcp_reuse_timeout */ - YYSYMBOL_server_tcp_auth_query_timeout = 439, /* server_tcp_auth_query_timeout */ - YYSYMBOL_server_tcp_keepalive = 440, /* server_tcp_keepalive */ - YYSYMBOL_server_tcp_keepalive_timeout = 441, /* server_tcp_keepalive_timeout */ - YYSYMBOL_server_sock_queue_timeout = 442, /* server_sock_queue_timeout */ - YYSYMBOL_server_tcp_upstream = 443, /* server_tcp_upstream */ - YYSYMBOL_server_udp_upstream_without_downstream = 444, /* server_udp_upstream_without_downstream */ - YYSYMBOL_server_ssl_upstream = 445, /* server_ssl_upstream */ - YYSYMBOL_server_ssl_service_key = 446, /* server_ssl_service_key */ - YYSYMBOL_server_ssl_service_pem = 447, /* server_ssl_service_pem */ - YYSYMBOL_server_ssl_port = 448, /* server_ssl_port */ - YYSYMBOL_server_tls_cert_bundle = 449, /* server_tls_cert_bundle */ - YYSYMBOL_server_tls_win_cert = 450, /* server_tls_win_cert */ - YYSYMBOL_server_tls_additional_port = 451, /* server_tls_additional_port */ - YYSYMBOL_server_tls_ciphers = 452, /* server_tls_ciphers */ - YYSYMBOL_server_tls_ciphersuites = 453, /* server_tls_ciphersuites */ - YYSYMBOL_server_tls_session_ticket_keys = 454, /* server_tls_session_ticket_keys */ - YYSYMBOL_server_tls_use_sni = 455, /* server_tls_use_sni */ - YYSYMBOL_server_https_port = 456, /* server_https_port */ - YYSYMBOL_server_http_endpoint = 457, /* server_http_endpoint */ - YYSYMBOL_server_http_max_streams = 458, /* server_http_max_streams */ - YYSYMBOL_server_http_query_buffer_size = 459, /* server_http_query_buffer_size */ - YYSYMBOL_server_http_response_buffer_size = 460, /* server_http_response_buffer_size */ - YYSYMBOL_server_http_nodelay = 461, /* server_http_nodelay */ - YYSYMBOL_server_http_notls_downstream = 462, /* server_http_notls_downstream */ - YYSYMBOL_server_quic_port = 463, /* server_quic_port */ - YYSYMBOL_server_quic_size = 464, /* server_quic_size */ - YYSYMBOL_server_use_systemd = 465, /* server_use_systemd */ - YYSYMBOL_server_do_daemonize = 466, /* server_do_daemonize */ - YYSYMBOL_server_use_syslog = 467, /* server_use_syslog */ - YYSYMBOL_server_log_time_ascii = 468, /* server_log_time_ascii */ - YYSYMBOL_server_log_time_iso = 469, /* server_log_time_iso */ - YYSYMBOL_server_log_queries = 470, /* server_log_queries */ - YYSYMBOL_server_log_replies = 471, /* server_log_replies */ - YYSYMBOL_server_log_tag_queryreply = 472, /* server_log_tag_queryreply */ - YYSYMBOL_server_log_servfail = 473, /* server_log_servfail */ - YYSYMBOL_server_log_destaddr = 474, /* server_log_destaddr */ - YYSYMBOL_server_log_local_actions = 475, /* server_log_local_actions */ - YYSYMBOL_server_chroot = 476, /* server_chroot */ - YYSYMBOL_server_username = 477, /* server_username */ - YYSYMBOL_server_directory = 478, /* server_directory */ - YYSYMBOL_server_logfile = 479, /* server_logfile */ - YYSYMBOL_server_pidfile = 480, /* server_pidfile */ - YYSYMBOL_server_root_hints = 481, /* server_root_hints */ - YYSYMBOL_server_dlv_anchor_file = 482, /* server_dlv_anchor_file */ - YYSYMBOL_server_dlv_anchor = 483, /* server_dlv_anchor */ - YYSYMBOL_server_auto_trust_anchor_file = 484, /* server_auto_trust_anchor_file */ - YYSYMBOL_server_trust_anchor_file = 485, /* server_trust_anchor_file */ - YYSYMBOL_server_trusted_keys_file = 486, /* server_trusted_keys_file */ - YYSYMBOL_server_trust_anchor = 487, /* server_trust_anchor */ - YYSYMBOL_server_trust_anchor_signaling = 488, /* server_trust_anchor_signaling */ - YYSYMBOL_server_root_key_sentinel = 489, /* server_root_key_sentinel */ - YYSYMBOL_server_domain_insecure = 490, /* server_domain_insecure */ - YYSYMBOL_server_hide_identity = 491, /* server_hide_identity */ - YYSYMBOL_server_hide_version = 492, /* server_hide_version */ - YYSYMBOL_server_hide_trustanchor = 493, /* server_hide_trustanchor */ - YYSYMBOL_server_hide_http_user_agent = 494, /* server_hide_http_user_agent */ - YYSYMBOL_server_identity = 495, /* server_identity */ - YYSYMBOL_server_version = 496, /* server_version */ - YYSYMBOL_server_http_user_agent = 497, /* server_http_user_agent */ - YYSYMBOL_server_nsid = 498, /* server_nsid */ - YYSYMBOL_server_so_rcvbuf = 499, /* server_so_rcvbuf */ - YYSYMBOL_server_so_sndbuf = 500, /* server_so_sndbuf */ - YYSYMBOL_server_so_reuseport = 501, /* server_so_reuseport */ - YYSYMBOL_server_ip_transparent = 502, /* server_ip_transparent */ - YYSYMBOL_server_ip_freebind = 503, /* server_ip_freebind */ - YYSYMBOL_server_ip_dscp = 504, /* server_ip_dscp */ - YYSYMBOL_server_stream_wait_size = 505, /* server_stream_wait_size */ - YYSYMBOL_server_edns_buffer_size = 506, /* server_edns_buffer_size */ - YYSYMBOL_server_msg_buffer_size = 507, /* server_msg_buffer_size */ - YYSYMBOL_server_msg_cache_size = 508, /* server_msg_cache_size */ - YYSYMBOL_server_msg_cache_slabs = 509, /* server_msg_cache_slabs */ - YYSYMBOL_server_num_queries_per_thread = 510, /* server_num_queries_per_thread */ - YYSYMBOL_server_jostle_timeout = 511, /* server_jostle_timeout */ - YYSYMBOL_server_delay_close = 512, /* server_delay_close */ - YYSYMBOL_server_udp_connect = 513, /* server_udp_connect */ - YYSYMBOL_server_unblock_lan_zones = 514, /* server_unblock_lan_zones */ - YYSYMBOL_server_insecure_lan_zones = 515, /* server_insecure_lan_zones */ - YYSYMBOL_server_rrset_cache_size = 516, /* server_rrset_cache_size */ - YYSYMBOL_server_rrset_cache_slabs = 517, /* server_rrset_cache_slabs */ - YYSYMBOL_server_infra_host_ttl = 518, /* server_infra_host_ttl */ - YYSYMBOL_server_infra_lame_ttl = 519, /* server_infra_lame_ttl */ - YYSYMBOL_server_infra_cache_numhosts = 520, /* server_infra_cache_numhosts */ - YYSYMBOL_server_infra_cache_lame_size = 521, /* server_infra_cache_lame_size */ - YYSYMBOL_server_infra_cache_slabs = 522, /* server_infra_cache_slabs */ - YYSYMBOL_server_infra_cache_min_rtt = 523, /* server_infra_cache_min_rtt */ - YYSYMBOL_server_infra_cache_max_rtt = 524, /* server_infra_cache_max_rtt */ - YYSYMBOL_server_infra_keep_probing = 525, /* server_infra_keep_probing */ - YYSYMBOL_server_target_fetch_policy = 526, /* server_target_fetch_policy */ - YYSYMBOL_server_harden_short_bufsize = 527, /* server_harden_short_bufsize */ - YYSYMBOL_server_harden_large_queries = 528, /* server_harden_large_queries */ - YYSYMBOL_server_harden_glue = 529, /* server_harden_glue */ - YYSYMBOL_server_harden_unverified_glue = 530, /* server_harden_unverified_glue */ - YYSYMBOL_server_harden_dnssec_stripped = 531, /* server_harden_dnssec_stripped */ - YYSYMBOL_server_harden_below_nxdomain = 532, /* server_harden_below_nxdomain */ - YYSYMBOL_server_harden_referral_path = 533, /* server_harden_referral_path */ - YYSYMBOL_server_harden_algo_downgrade = 534, /* server_harden_algo_downgrade */ - YYSYMBOL_server_harden_unknown_additional = 535, /* server_harden_unknown_additional */ - YYSYMBOL_server_use_caps_for_id = 536, /* server_use_caps_for_id */ - YYSYMBOL_server_caps_whitelist = 537, /* server_caps_whitelist */ - YYSYMBOL_server_private_address = 538, /* server_private_address */ - YYSYMBOL_server_private_domain = 539, /* server_private_domain */ - YYSYMBOL_server_prefetch = 540, /* server_prefetch */ - YYSYMBOL_server_prefetch_key = 541, /* server_prefetch_key */ - YYSYMBOL_server_deny_any = 542, /* server_deny_any */ - YYSYMBOL_server_unwanted_reply_threshold = 543, /* server_unwanted_reply_threshold */ - YYSYMBOL_server_do_not_query_address = 544, /* server_do_not_query_address */ - YYSYMBOL_server_do_not_query_localhost = 545, /* server_do_not_query_localhost */ - YYSYMBOL_server_access_control = 546, /* server_access_control */ - YYSYMBOL_server_interface_action = 547, /* server_interface_action */ - YYSYMBOL_server_module_conf = 548, /* server_module_conf */ - YYSYMBOL_server_val_override_date = 549, /* server_val_override_date */ - YYSYMBOL_server_val_sig_skew_min = 550, /* server_val_sig_skew_min */ - YYSYMBOL_server_val_sig_skew_max = 551, /* server_val_sig_skew_max */ - YYSYMBOL_server_val_max_restart = 552, /* server_val_max_restart */ - YYSYMBOL_server_cache_max_ttl = 553, /* server_cache_max_ttl */ - YYSYMBOL_server_cache_max_negative_ttl = 554, /* server_cache_max_negative_ttl */ - YYSYMBOL_server_cache_min_negative_ttl = 555, /* server_cache_min_negative_ttl */ - YYSYMBOL_server_cache_min_ttl = 556, /* server_cache_min_ttl */ - YYSYMBOL_server_bogus_ttl = 557, /* server_bogus_ttl */ - YYSYMBOL_server_val_clean_additional = 558, /* server_val_clean_additional */ - YYSYMBOL_server_val_permissive_mode = 559, /* server_val_permissive_mode */ - YYSYMBOL_server_aggressive_nsec = 560, /* server_aggressive_nsec */ - YYSYMBOL_server_ignore_cd_flag = 561, /* server_ignore_cd_flag */ - YYSYMBOL_server_disable_edns_do = 562, /* server_disable_edns_do */ - YYSYMBOL_server_serve_expired = 563, /* server_serve_expired */ - YYSYMBOL_server_serve_expired_ttl = 564, /* server_serve_expired_ttl */ - YYSYMBOL_server_serve_expired_ttl_reset = 565, /* server_serve_expired_ttl_reset */ - YYSYMBOL_server_serve_expired_reply_ttl = 566, /* server_serve_expired_reply_ttl */ - YYSYMBOL_server_serve_expired_client_timeout = 567, /* server_serve_expired_client_timeout */ - YYSYMBOL_server_ede_serve_expired = 568, /* server_ede_serve_expired */ - YYSYMBOL_server_serve_original_ttl = 569, /* server_serve_original_ttl */ - YYSYMBOL_server_fake_dsa = 570, /* server_fake_dsa */ - YYSYMBOL_server_fake_sha1 = 571, /* server_fake_sha1 */ - YYSYMBOL_server_val_log_level = 572, /* server_val_log_level */ - YYSYMBOL_server_val_nsec3_keysize_iterations = 573, /* server_val_nsec3_keysize_iterations */ - YYSYMBOL_server_zonemd_permissive_mode = 574, /* server_zonemd_permissive_mode */ - YYSYMBOL_server_add_holddown = 575, /* server_add_holddown */ - YYSYMBOL_server_del_holddown = 576, /* server_del_holddown */ - YYSYMBOL_server_keep_missing = 577, /* server_keep_missing */ - YYSYMBOL_server_permit_small_holddown = 578, /* server_permit_small_holddown */ - YYSYMBOL_server_key_cache_size = 579, /* server_key_cache_size */ - YYSYMBOL_server_key_cache_slabs = 580, /* server_key_cache_slabs */ - YYSYMBOL_server_neg_cache_size = 581, /* server_neg_cache_size */ - YYSYMBOL_server_local_zone = 582, /* server_local_zone */ - YYSYMBOL_server_local_data = 583, /* server_local_data */ - YYSYMBOL_server_local_data_ptr = 584, /* server_local_data_ptr */ - YYSYMBOL_server_minimal_responses = 585, /* server_minimal_responses */ - YYSYMBOL_server_rrset_roundrobin = 586, /* server_rrset_roundrobin */ - YYSYMBOL_server_unknown_server_time_limit = 587, /* server_unknown_server_time_limit */ - YYSYMBOL_server_discard_timeout = 588, /* server_discard_timeout */ - YYSYMBOL_server_wait_limit = 589, /* server_wait_limit */ - YYSYMBOL_server_wait_limit_cookie = 590, /* server_wait_limit_cookie */ - YYSYMBOL_server_wait_limit_netblock = 591, /* server_wait_limit_netblock */ - YYSYMBOL_server_wait_limit_cookie_netblock = 592, /* server_wait_limit_cookie_netblock */ - YYSYMBOL_server_max_udp_size = 593, /* server_max_udp_size */ - YYSYMBOL_server_dns64_prefix = 594, /* server_dns64_prefix */ - YYSYMBOL_server_dns64_synthall = 595, /* server_dns64_synthall */ - YYSYMBOL_server_dns64_ignore_aaaa = 596, /* server_dns64_ignore_aaaa */ - YYSYMBOL_server_nat64_prefix = 597, /* server_nat64_prefix */ - YYSYMBOL_server_define_tag = 598, /* server_define_tag */ - YYSYMBOL_server_local_zone_tag = 599, /* server_local_zone_tag */ - YYSYMBOL_server_access_control_tag = 600, /* server_access_control_tag */ - YYSYMBOL_server_access_control_tag_action = 601, /* server_access_control_tag_action */ - YYSYMBOL_server_access_control_tag_data = 602, /* server_access_control_tag_data */ - YYSYMBOL_server_local_zone_override = 603, /* server_local_zone_override */ - YYSYMBOL_server_access_control_view = 604, /* server_access_control_view */ - YYSYMBOL_server_interface_tag = 605, /* server_interface_tag */ - YYSYMBOL_server_interface_tag_action = 606, /* server_interface_tag_action */ - YYSYMBOL_server_interface_tag_data = 607, /* server_interface_tag_data */ - YYSYMBOL_server_interface_view = 608, /* server_interface_view */ - YYSYMBOL_server_response_ip_tag = 609, /* server_response_ip_tag */ - YYSYMBOL_server_ip_ratelimit = 610, /* server_ip_ratelimit */ - YYSYMBOL_server_ip_ratelimit_cookie = 611, /* server_ip_ratelimit_cookie */ - YYSYMBOL_server_ratelimit = 612, /* server_ratelimit */ - YYSYMBOL_server_ip_ratelimit_size = 613, /* server_ip_ratelimit_size */ - YYSYMBOL_server_ratelimit_size = 614, /* server_ratelimit_size */ - YYSYMBOL_server_ip_ratelimit_slabs = 615, /* server_ip_ratelimit_slabs */ - YYSYMBOL_server_ratelimit_slabs = 616, /* server_ratelimit_slabs */ - YYSYMBOL_server_ratelimit_for_domain = 617, /* server_ratelimit_for_domain */ - YYSYMBOL_server_ratelimit_below_domain = 618, /* server_ratelimit_below_domain */ - YYSYMBOL_server_ip_ratelimit_factor = 619, /* server_ip_ratelimit_factor */ - YYSYMBOL_server_ratelimit_factor = 620, /* server_ratelimit_factor */ - YYSYMBOL_server_ip_ratelimit_backoff = 621, /* server_ip_ratelimit_backoff */ - YYSYMBOL_server_ratelimit_backoff = 622, /* server_ratelimit_backoff */ - YYSYMBOL_server_outbound_msg_retry = 623, /* server_outbound_msg_retry */ - YYSYMBOL_server_max_sent_count = 624, /* server_max_sent_count */ - YYSYMBOL_server_max_query_restarts = 625, /* server_max_query_restarts */ - YYSYMBOL_server_low_rtt = 626, /* server_low_rtt */ - YYSYMBOL_server_fast_server_num = 627, /* server_fast_server_num */ - YYSYMBOL_server_fast_server_permil = 628, /* server_fast_server_permil */ - YYSYMBOL_server_qname_minimisation = 629, /* server_qname_minimisation */ - YYSYMBOL_server_qname_minimisation_strict = 630, /* server_qname_minimisation_strict */ - YYSYMBOL_server_pad_responses = 631, /* server_pad_responses */ - YYSYMBOL_server_pad_responses_block_size = 632, /* server_pad_responses_block_size */ - YYSYMBOL_server_pad_queries = 633, /* server_pad_queries */ - YYSYMBOL_server_pad_queries_block_size = 634, /* server_pad_queries_block_size */ - YYSYMBOL_server_ipsecmod_enabled = 635, /* server_ipsecmod_enabled */ - YYSYMBOL_server_ipsecmod_ignore_bogus = 636, /* server_ipsecmod_ignore_bogus */ - YYSYMBOL_server_ipsecmod_hook = 637, /* server_ipsecmod_hook */ - YYSYMBOL_server_ipsecmod_max_ttl = 638, /* server_ipsecmod_max_ttl */ - YYSYMBOL_server_ipsecmod_whitelist = 639, /* server_ipsecmod_whitelist */ - YYSYMBOL_server_ipsecmod_strict = 640, /* server_ipsecmod_strict */ - YYSYMBOL_server_edns_client_string = 641, /* server_edns_client_string */ - YYSYMBOL_server_edns_client_string_opcode = 642, /* server_edns_client_string_opcode */ - YYSYMBOL_server_ede = 643, /* server_ede */ - YYSYMBOL_server_proxy_protocol_port = 644, /* server_proxy_protocol_port */ - YYSYMBOL_stub_name = 645, /* stub_name */ - YYSYMBOL_stub_host = 646, /* stub_host */ - YYSYMBOL_stub_addr = 647, /* stub_addr */ - YYSYMBOL_stub_first = 648, /* stub_first */ - YYSYMBOL_stub_no_cache = 649, /* stub_no_cache */ - YYSYMBOL_stub_ssl_upstream = 650, /* stub_ssl_upstream */ - YYSYMBOL_stub_tcp_upstream = 651, /* stub_tcp_upstream */ - YYSYMBOL_stub_prime = 652, /* stub_prime */ - YYSYMBOL_forward_name = 653, /* forward_name */ - YYSYMBOL_forward_host = 654, /* forward_host */ - YYSYMBOL_forward_addr = 655, /* forward_addr */ - YYSYMBOL_forward_first = 656, /* forward_first */ - YYSYMBOL_forward_no_cache = 657, /* forward_no_cache */ - YYSYMBOL_forward_ssl_upstream = 658, /* forward_ssl_upstream */ - YYSYMBOL_forward_tcp_upstream = 659, /* forward_tcp_upstream */ - YYSYMBOL_auth_name = 660, /* auth_name */ - YYSYMBOL_auth_zonefile = 661, /* auth_zonefile */ - YYSYMBOL_auth_master = 662, /* auth_master */ - YYSYMBOL_auth_url = 663, /* auth_url */ - YYSYMBOL_auth_allow_notify = 664, /* auth_allow_notify */ - YYSYMBOL_auth_zonemd_check = 665, /* auth_zonemd_check */ - YYSYMBOL_auth_zonemd_reject_absence = 666, /* auth_zonemd_reject_absence */ - YYSYMBOL_auth_for_downstream = 667, /* auth_for_downstream */ - YYSYMBOL_auth_for_upstream = 668, /* auth_for_upstream */ - YYSYMBOL_auth_fallback_enabled = 669, /* auth_fallback_enabled */ - YYSYMBOL_view_name = 670, /* view_name */ - YYSYMBOL_view_local_zone = 671, /* view_local_zone */ - YYSYMBOL_view_response_ip = 672, /* view_response_ip */ - YYSYMBOL_view_response_ip_data = 673, /* view_response_ip_data */ - YYSYMBOL_view_local_data = 674, /* view_local_data */ - YYSYMBOL_view_local_data_ptr = 675, /* view_local_data_ptr */ - YYSYMBOL_view_first = 676, /* view_first */ - YYSYMBOL_rcstart = 677, /* rcstart */ - YYSYMBOL_contents_rc = 678, /* contents_rc */ - YYSYMBOL_content_rc = 679, /* content_rc */ - YYSYMBOL_rc_control_enable = 680, /* rc_control_enable */ - YYSYMBOL_rc_control_port = 681, /* rc_control_port */ - YYSYMBOL_rc_control_interface = 682, /* rc_control_interface */ - YYSYMBOL_rc_control_use_cert = 683, /* rc_control_use_cert */ - YYSYMBOL_rc_server_key_file = 684, /* rc_server_key_file */ - YYSYMBOL_rc_server_cert_file = 685, /* rc_server_cert_file */ - YYSYMBOL_rc_control_key_file = 686, /* rc_control_key_file */ - YYSYMBOL_rc_control_cert_file = 687, /* rc_control_cert_file */ - YYSYMBOL_dtstart = 688, /* dtstart */ - YYSYMBOL_contents_dt = 689, /* contents_dt */ - YYSYMBOL_content_dt = 690, /* content_dt */ - YYSYMBOL_dt_dnstap_enable = 691, /* dt_dnstap_enable */ - YYSYMBOL_dt_dnstap_bidirectional = 692, /* dt_dnstap_bidirectional */ - YYSYMBOL_dt_dnstap_socket_path = 693, /* dt_dnstap_socket_path */ - YYSYMBOL_dt_dnstap_ip = 694, /* dt_dnstap_ip */ - YYSYMBOL_dt_dnstap_tls = 695, /* dt_dnstap_tls */ - YYSYMBOL_dt_dnstap_tls_server_name = 696, /* dt_dnstap_tls_server_name */ - YYSYMBOL_dt_dnstap_tls_cert_bundle = 697, /* dt_dnstap_tls_cert_bundle */ - YYSYMBOL_dt_dnstap_tls_client_key_file = 698, /* dt_dnstap_tls_client_key_file */ - YYSYMBOL_dt_dnstap_tls_client_cert_file = 699, /* dt_dnstap_tls_client_cert_file */ - YYSYMBOL_dt_dnstap_send_identity = 700, /* dt_dnstap_send_identity */ - YYSYMBOL_dt_dnstap_send_version = 701, /* dt_dnstap_send_version */ - YYSYMBOL_dt_dnstap_identity = 702, /* dt_dnstap_identity */ - YYSYMBOL_dt_dnstap_version = 703, /* dt_dnstap_version */ - YYSYMBOL_dt_dnstap_log_resolver_query_messages = 704, /* dt_dnstap_log_resolver_query_messages */ - YYSYMBOL_dt_dnstap_log_resolver_response_messages = 705, /* dt_dnstap_log_resolver_response_messages */ - YYSYMBOL_dt_dnstap_log_client_query_messages = 706, /* dt_dnstap_log_client_query_messages */ - YYSYMBOL_dt_dnstap_log_client_response_messages = 707, /* dt_dnstap_log_client_response_messages */ - YYSYMBOL_dt_dnstap_log_forwarder_query_messages = 708, /* dt_dnstap_log_forwarder_query_messages */ - YYSYMBOL_dt_dnstap_log_forwarder_response_messages = 709, /* dt_dnstap_log_forwarder_response_messages */ - YYSYMBOL_dt_dnstap_sample_rate = 710, /* dt_dnstap_sample_rate */ - YYSYMBOL_pythonstart = 711, /* pythonstart */ - YYSYMBOL_contents_py = 712, /* contents_py */ - YYSYMBOL_content_py = 713, /* content_py */ - YYSYMBOL_py_script = 714, /* py_script */ - YYSYMBOL_dynlibstart = 715, /* dynlibstart */ - YYSYMBOL_contents_dl = 716, /* contents_dl */ - YYSYMBOL_content_dl = 717, /* content_dl */ - YYSYMBOL_dl_file = 718, /* dl_file */ - YYSYMBOL_server_disable_dnssec_lame_check = 719, /* server_disable_dnssec_lame_check */ - YYSYMBOL_server_log_identity = 720, /* server_log_identity */ - YYSYMBOL_server_response_ip = 721, /* server_response_ip */ - YYSYMBOL_server_response_ip_data = 722, /* server_response_ip_data */ - YYSYMBOL_dnscstart = 723, /* dnscstart */ - YYSYMBOL_contents_dnsc = 724, /* contents_dnsc */ - YYSYMBOL_content_dnsc = 725, /* content_dnsc */ - YYSYMBOL_dnsc_dnscrypt_enable = 726, /* dnsc_dnscrypt_enable */ - YYSYMBOL_dnsc_dnscrypt_port = 727, /* dnsc_dnscrypt_port */ - YYSYMBOL_dnsc_dnscrypt_provider = 728, /* dnsc_dnscrypt_provider */ - YYSYMBOL_dnsc_dnscrypt_provider_cert = 729, /* dnsc_dnscrypt_provider_cert */ - YYSYMBOL_dnsc_dnscrypt_provider_cert_rotated = 730, /* dnsc_dnscrypt_provider_cert_rotated */ - YYSYMBOL_dnsc_dnscrypt_secret_key = 731, /* dnsc_dnscrypt_secret_key */ - YYSYMBOL_dnsc_dnscrypt_shared_secret_cache_size = 732, /* dnsc_dnscrypt_shared_secret_cache_size */ - YYSYMBOL_dnsc_dnscrypt_shared_secret_cache_slabs = 733, /* dnsc_dnscrypt_shared_secret_cache_slabs */ - YYSYMBOL_dnsc_dnscrypt_nonce_cache_size = 734, /* dnsc_dnscrypt_nonce_cache_size */ - YYSYMBOL_dnsc_dnscrypt_nonce_cache_slabs = 735, /* dnsc_dnscrypt_nonce_cache_slabs */ - YYSYMBOL_cachedbstart = 736, /* cachedbstart */ - YYSYMBOL_contents_cachedb = 737, /* contents_cachedb */ - YYSYMBOL_content_cachedb = 738, /* content_cachedb */ - YYSYMBOL_cachedb_backend_name = 739, /* cachedb_backend_name */ - YYSYMBOL_cachedb_secret_seed = 740, /* cachedb_secret_seed */ - YYSYMBOL_cachedb_no_store = 741, /* cachedb_no_store */ - YYSYMBOL_cachedb_check_when_serve_expired = 742, /* cachedb_check_when_serve_expired */ - YYSYMBOL_redis_server_host = 743, /* redis_server_host */ - YYSYMBOL_redis_server_port = 744, /* redis_server_port */ - YYSYMBOL_redis_server_path = 745, /* redis_server_path */ - YYSYMBOL_redis_server_password = 746, /* redis_server_password */ - YYSYMBOL_redis_timeout = 747, /* redis_timeout */ - YYSYMBOL_redis_command_timeout = 748, /* redis_command_timeout */ - YYSYMBOL_redis_connect_timeout = 749, /* redis_connect_timeout */ - YYSYMBOL_redis_expire_records = 750, /* redis_expire_records */ - YYSYMBOL_redis_logical_db = 751, /* redis_logical_db */ - YYSYMBOL_server_tcp_connection_limit = 752, /* server_tcp_connection_limit */ - YYSYMBOL_server_answer_cookie = 753, /* server_answer_cookie */ - YYSYMBOL_server_cookie_secret = 754, /* server_cookie_secret */ - YYSYMBOL_server_cookie_secret_file = 755, /* server_cookie_secret_file */ - YYSYMBOL_server_iter_scrub_ns = 756, /* server_iter_scrub_ns */ - YYSYMBOL_server_iter_scrub_cname = 757, /* server_iter_scrub_cname */ - YYSYMBOL_server_max_global_quota = 758, /* server_max_global_quota */ - YYSYMBOL_ipsetstart = 759, /* ipsetstart */ - YYSYMBOL_contents_ipset = 760, /* contents_ipset */ - YYSYMBOL_content_ipset = 761, /* content_ipset */ - YYSYMBOL_ipset_name_v4 = 762, /* ipset_name_v4 */ - YYSYMBOL_ipset_name_v6 = 763 /* ipset_name_v6 */ + YYSYMBOL_VAR_CACHEDB_REDISREPLICAHOST = 285, /* VAR_CACHEDB_REDISREPLICAHOST */ + YYSYMBOL_VAR_CACHEDB_REDISPORT = 286, /* VAR_CACHEDB_REDISPORT */ + YYSYMBOL_VAR_CACHEDB_REDISREPLICAPORT = 287, /* VAR_CACHEDB_REDISREPLICAPORT */ + YYSYMBOL_VAR_CACHEDB_REDISTIMEOUT = 288, /* VAR_CACHEDB_REDISTIMEOUT */ + YYSYMBOL_VAR_CACHEDB_REDISREPLICATIMEOUT = 289, /* VAR_CACHEDB_REDISREPLICATIMEOUT */ + YYSYMBOL_VAR_CACHEDB_REDISEXPIRERECORDS = 290, /* VAR_CACHEDB_REDISEXPIRERECORDS */ + YYSYMBOL_VAR_CACHEDB_REDISPATH = 291, /* VAR_CACHEDB_REDISPATH */ + YYSYMBOL_VAR_CACHEDB_REDISREPLICAPATH = 292, /* VAR_CACHEDB_REDISREPLICAPATH */ + YYSYMBOL_VAR_CACHEDB_REDISPASSWORD = 293, /* VAR_CACHEDB_REDISPASSWORD */ + YYSYMBOL_VAR_CACHEDB_REDISREPLICAPASSWORD = 294, /* VAR_CACHEDB_REDISREPLICAPASSWORD */ + YYSYMBOL_VAR_CACHEDB_REDISLOGICALDB = 295, /* VAR_CACHEDB_REDISLOGICALDB */ + YYSYMBOL_VAR_CACHEDB_REDISREPLICALOGICALDB = 296, /* VAR_CACHEDB_REDISREPLICALOGICALDB */ + YYSYMBOL_VAR_CACHEDB_REDISCOMMANDTIMEOUT = 297, /* VAR_CACHEDB_REDISCOMMANDTIMEOUT */ + YYSYMBOL_VAR_CACHEDB_REDISREPLICACOMMANDTIMEOUT = 298, /* VAR_CACHEDB_REDISREPLICACOMMANDTIMEOUT */ + YYSYMBOL_VAR_CACHEDB_REDISCONNECTTIMEOUT = 299, /* VAR_CACHEDB_REDISCONNECTTIMEOUT */ + YYSYMBOL_VAR_CACHEDB_REDISREPLICACONNECTTIMEOUT = 300, /* VAR_CACHEDB_REDISREPLICACONNECTTIMEOUT */ + YYSYMBOL_VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 301, /* VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM */ + YYSYMBOL_VAR_FOR_UPSTREAM = 302, /* VAR_FOR_UPSTREAM */ + YYSYMBOL_VAR_AUTH_ZONE = 303, /* VAR_AUTH_ZONE */ + YYSYMBOL_VAR_ZONEFILE = 304, /* VAR_ZONEFILE */ + YYSYMBOL_VAR_MASTER = 305, /* VAR_MASTER */ + YYSYMBOL_VAR_URL = 306, /* VAR_URL */ + YYSYMBOL_VAR_FOR_DOWNSTREAM = 307, /* VAR_FOR_DOWNSTREAM */ + YYSYMBOL_VAR_FALLBACK_ENABLED = 308, /* VAR_FALLBACK_ENABLED */ + YYSYMBOL_VAR_TLS_ADDITIONAL_PORT = 309, /* VAR_TLS_ADDITIONAL_PORT */ + YYSYMBOL_VAR_LOW_RTT = 310, /* VAR_LOW_RTT */ + YYSYMBOL_VAR_LOW_RTT_PERMIL = 311, /* VAR_LOW_RTT_PERMIL */ + YYSYMBOL_VAR_FAST_SERVER_PERMIL = 312, /* VAR_FAST_SERVER_PERMIL */ + YYSYMBOL_VAR_FAST_SERVER_NUM = 313, /* VAR_FAST_SERVER_NUM */ + YYSYMBOL_VAR_ALLOW_NOTIFY = 314, /* VAR_ALLOW_NOTIFY */ + YYSYMBOL_VAR_TLS_WIN_CERT = 315, /* VAR_TLS_WIN_CERT */ + YYSYMBOL_VAR_TCP_CONNECTION_LIMIT = 316, /* VAR_TCP_CONNECTION_LIMIT */ + YYSYMBOL_VAR_ANSWER_COOKIE = 317, /* VAR_ANSWER_COOKIE */ + YYSYMBOL_VAR_COOKIE_SECRET = 318, /* VAR_COOKIE_SECRET */ + YYSYMBOL_VAR_IP_RATELIMIT_COOKIE = 319, /* VAR_IP_RATELIMIT_COOKIE */ + YYSYMBOL_VAR_FORWARD_NO_CACHE = 320, /* VAR_FORWARD_NO_CACHE */ + YYSYMBOL_VAR_STUB_NO_CACHE = 321, /* VAR_STUB_NO_CACHE */ + YYSYMBOL_VAR_LOG_SERVFAIL = 322, /* VAR_LOG_SERVFAIL */ + YYSYMBOL_VAR_DENY_ANY = 323, /* VAR_DENY_ANY */ + YYSYMBOL_VAR_UNKNOWN_SERVER_TIME_LIMIT = 324, /* VAR_UNKNOWN_SERVER_TIME_LIMIT */ + YYSYMBOL_VAR_LOG_TAG_QUERYREPLY = 325, /* VAR_LOG_TAG_QUERYREPLY */ + YYSYMBOL_VAR_DISCARD_TIMEOUT = 326, /* VAR_DISCARD_TIMEOUT */ + YYSYMBOL_VAR_WAIT_LIMIT = 327, /* VAR_WAIT_LIMIT */ + YYSYMBOL_VAR_WAIT_LIMIT_COOKIE = 328, /* VAR_WAIT_LIMIT_COOKIE */ + YYSYMBOL_VAR_WAIT_LIMIT_NETBLOCK = 329, /* VAR_WAIT_LIMIT_NETBLOCK */ + YYSYMBOL_VAR_WAIT_LIMIT_COOKIE_NETBLOCK = 330, /* VAR_WAIT_LIMIT_COOKIE_NETBLOCK */ + YYSYMBOL_VAR_STREAM_WAIT_SIZE = 331, /* VAR_STREAM_WAIT_SIZE */ + YYSYMBOL_VAR_TLS_CIPHERS = 332, /* VAR_TLS_CIPHERS */ + YYSYMBOL_VAR_TLS_CIPHERSUITES = 333, /* VAR_TLS_CIPHERSUITES */ + YYSYMBOL_VAR_TLS_USE_SNI = 334, /* VAR_TLS_USE_SNI */ + YYSYMBOL_VAR_IPSET = 335, /* VAR_IPSET */ + YYSYMBOL_VAR_IPSET_NAME_V4 = 336, /* VAR_IPSET_NAME_V4 */ + YYSYMBOL_VAR_IPSET_NAME_V6 = 337, /* VAR_IPSET_NAME_V6 */ + YYSYMBOL_VAR_TLS_SESSION_TICKET_KEYS = 338, /* VAR_TLS_SESSION_TICKET_KEYS */ + YYSYMBOL_VAR_RPZ = 339, /* VAR_RPZ */ + YYSYMBOL_VAR_TAGS = 340, /* VAR_TAGS */ + YYSYMBOL_VAR_RPZ_ACTION_OVERRIDE = 341, /* VAR_RPZ_ACTION_OVERRIDE */ + YYSYMBOL_VAR_RPZ_CNAME_OVERRIDE = 342, /* VAR_RPZ_CNAME_OVERRIDE */ + YYSYMBOL_VAR_RPZ_LOG = 343, /* VAR_RPZ_LOG */ + YYSYMBOL_VAR_RPZ_LOG_NAME = 344, /* VAR_RPZ_LOG_NAME */ + YYSYMBOL_VAR_DYNLIB = 345, /* VAR_DYNLIB */ + YYSYMBOL_VAR_DYNLIB_FILE = 346, /* VAR_DYNLIB_FILE */ + YYSYMBOL_VAR_EDNS_CLIENT_STRING = 347, /* VAR_EDNS_CLIENT_STRING */ + YYSYMBOL_VAR_EDNS_CLIENT_STRING_OPCODE = 348, /* VAR_EDNS_CLIENT_STRING_OPCODE */ + YYSYMBOL_VAR_NSID = 349, /* VAR_NSID */ + YYSYMBOL_VAR_ZONEMD_PERMISSIVE_MODE = 350, /* VAR_ZONEMD_PERMISSIVE_MODE */ + YYSYMBOL_VAR_ZONEMD_CHECK = 351, /* VAR_ZONEMD_CHECK */ + YYSYMBOL_VAR_ZONEMD_REJECT_ABSENCE = 352, /* VAR_ZONEMD_REJECT_ABSENCE */ + YYSYMBOL_VAR_RPZ_SIGNAL_NXDOMAIN_RA = 353, /* VAR_RPZ_SIGNAL_NXDOMAIN_RA */ + YYSYMBOL_VAR_INTERFACE_AUTOMATIC_PORTS = 354, /* VAR_INTERFACE_AUTOMATIC_PORTS */ + YYSYMBOL_VAR_EDE = 355, /* VAR_EDE */ + YYSYMBOL_VAR_DNS_ERROR_REPORTING = 356, /* VAR_DNS_ERROR_REPORTING */ + YYSYMBOL_VAR_INTERFACE_ACTION = 357, /* VAR_INTERFACE_ACTION */ + YYSYMBOL_VAR_INTERFACE_VIEW = 358, /* VAR_INTERFACE_VIEW */ + YYSYMBOL_VAR_INTERFACE_TAG = 359, /* VAR_INTERFACE_TAG */ + YYSYMBOL_VAR_INTERFACE_TAG_ACTION = 360, /* VAR_INTERFACE_TAG_ACTION */ + YYSYMBOL_VAR_INTERFACE_TAG_DATA = 361, /* VAR_INTERFACE_TAG_DATA */ + YYSYMBOL_VAR_QUIC_PORT = 362, /* VAR_QUIC_PORT */ + YYSYMBOL_VAR_QUIC_SIZE = 363, /* VAR_QUIC_SIZE */ + YYSYMBOL_VAR_PROXY_PROTOCOL_PORT = 364, /* VAR_PROXY_PROTOCOL_PORT */ + YYSYMBOL_VAR_STATISTICS_INHIBIT_ZERO = 365, /* VAR_STATISTICS_INHIBIT_ZERO */ + YYSYMBOL_VAR_HARDEN_UNKNOWN_ADDITIONAL = 366, /* VAR_HARDEN_UNKNOWN_ADDITIONAL */ + YYSYMBOL_VAR_DISABLE_EDNS_DO = 367, /* VAR_DISABLE_EDNS_DO */ + YYSYMBOL_VAR_CACHEDB_NO_STORE = 368, /* VAR_CACHEDB_NO_STORE */ + YYSYMBOL_VAR_LOG_DESTADDR = 369, /* VAR_LOG_DESTADDR */ + YYSYMBOL_VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED = 370, /* VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED */ + YYSYMBOL_VAR_COOKIE_SECRET_FILE = 371, /* VAR_COOKIE_SECRET_FILE */ + YYSYMBOL_VAR_ITER_SCRUB_NS = 372, /* VAR_ITER_SCRUB_NS */ + YYSYMBOL_VAR_ITER_SCRUB_CNAME = 373, /* VAR_ITER_SCRUB_CNAME */ + YYSYMBOL_VAR_MAX_GLOBAL_QUOTA = 374, /* VAR_MAX_GLOBAL_QUOTA */ + YYSYMBOL_VAR_HARDEN_UNVERIFIED_GLUE = 375, /* VAR_HARDEN_UNVERIFIED_GLUE */ + YYSYMBOL_VAR_LOG_TIME_ISO = 376, /* VAR_LOG_TIME_ISO */ + YYSYMBOL_YYACCEPT = 377, /* $accept */ + YYSYMBOL_toplevelvars = 378, /* toplevelvars */ + YYSYMBOL_toplevelvar = 379, /* toplevelvar */ + YYSYMBOL_force_toplevel = 380, /* force_toplevel */ + YYSYMBOL_serverstart = 381, /* serverstart */ + YYSYMBOL_contents_server = 382, /* contents_server */ + YYSYMBOL_content_server = 383, /* content_server */ + YYSYMBOL_stub_clause = 384, /* stub_clause */ + YYSYMBOL_stubstart = 385, /* stubstart */ + YYSYMBOL_contents_stub = 386, /* contents_stub */ + YYSYMBOL_content_stub = 387, /* content_stub */ + YYSYMBOL_forward_clause = 388, /* forward_clause */ + YYSYMBOL_forwardstart = 389, /* forwardstart */ + YYSYMBOL_contents_forward = 390, /* contents_forward */ + YYSYMBOL_content_forward = 391, /* content_forward */ + YYSYMBOL_view_clause = 392, /* view_clause */ + YYSYMBOL_viewstart = 393, /* viewstart */ + YYSYMBOL_contents_view = 394, /* contents_view */ + YYSYMBOL_content_view = 395, /* content_view */ + YYSYMBOL_authstart = 396, /* authstart */ + YYSYMBOL_contents_auth = 397, /* contents_auth */ + YYSYMBOL_content_auth = 398, /* content_auth */ + YYSYMBOL_rpz_tag = 399, /* rpz_tag */ + YYSYMBOL_rpz_action_override = 400, /* rpz_action_override */ + YYSYMBOL_rpz_cname_override = 401, /* rpz_cname_override */ + YYSYMBOL_rpz_log = 402, /* rpz_log */ + YYSYMBOL_rpz_log_name = 403, /* rpz_log_name */ + YYSYMBOL_rpz_signal_nxdomain_ra = 404, /* rpz_signal_nxdomain_ra */ + YYSYMBOL_rpzstart = 405, /* rpzstart */ + YYSYMBOL_contents_rpz = 406, /* contents_rpz */ + YYSYMBOL_content_rpz = 407, /* content_rpz */ + YYSYMBOL_server_num_threads = 408, /* server_num_threads */ + YYSYMBOL_server_verbosity = 409, /* server_verbosity */ + YYSYMBOL_server_statistics_interval = 410, /* server_statistics_interval */ + YYSYMBOL_server_statistics_cumulative = 411, /* server_statistics_cumulative */ + YYSYMBOL_server_extended_statistics = 412, /* server_extended_statistics */ + YYSYMBOL_server_statistics_inhibit_zero = 413, /* server_statistics_inhibit_zero */ + YYSYMBOL_server_shm_enable = 414, /* server_shm_enable */ + YYSYMBOL_server_shm_key = 415, /* server_shm_key */ + YYSYMBOL_server_port = 416, /* server_port */ + YYSYMBOL_server_send_client_subnet = 417, /* server_send_client_subnet */ + YYSYMBOL_server_client_subnet_zone = 418, /* server_client_subnet_zone */ + YYSYMBOL_server_client_subnet_always_forward = 419, /* server_client_subnet_always_forward */ + YYSYMBOL_server_client_subnet_opcode = 420, /* server_client_subnet_opcode */ + YYSYMBOL_server_max_client_subnet_ipv4 = 421, /* server_max_client_subnet_ipv4 */ + YYSYMBOL_server_max_client_subnet_ipv6 = 422, /* server_max_client_subnet_ipv6 */ + YYSYMBOL_server_min_client_subnet_ipv4 = 423, /* server_min_client_subnet_ipv4 */ + YYSYMBOL_server_min_client_subnet_ipv6 = 424, /* server_min_client_subnet_ipv6 */ + YYSYMBOL_server_max_ecs_tree_size_ipv4 = 425, /* server_max_ecs_tree_size_ipv4 */ + YYSYMBOL_server_max_ecs_tree_size_ipv6 = 426, /* server_max_ecs_tree_size_ipv6 */ + YYSYMBOL_server_interface = 427, /* server_interface */ + YYSYMBOL_server_outgoing_interface = 428, /* server_outgoing_interface */ + YYSYMBOL_server_outgoing_range = 429, /* server_outgoing_range */ + YYSYMBOL_server_outgoing_port_permit = 430, /* server_outgoing_port_permit */ + YYSYMBOL_server_outgoing_port_avoid = 431, /* server_outgoing_port_avoid */ + YYSYMBOL_server_outgoing_num_tcp = 432, /* server_outgoing_num_tcp */ + YYSYMBOL_server_incoming_num_tcp = 433, /* server_incoming_num_tcp */ + YYSYMBOL_server_interface_automatic = 434, /* server_interface_automatic */ + YYSYMBOL_server_interface_automatic_ports = 435, /* server_interface_automatic_ports */ + YYSYMBOL_server_do_ip4 = 436, /* server_do_ip4 */ + YYSYMBOL_server_do_ip6 = 437, /* server_do_ip6 */ + YYSYMBOL_server_do_nat64 = 438, /* server_do_nat64 */ + YYSYMBOL_server_do_udp = 439, /* server_do_udp */ + YYSYMBOL_server_do_tcp = 440, /* server_do_tcp */ + YYSYMBOL_server_prefer_ip4 = 441, /* server_prefer_ip4 */ + YYSYMBOL_server_prefer_ip6 = 442, /* server_prefer_ip6 */ + YYSYMBOL_server_tcp_mss = 443, /* server_tcp_mss */ + YYSYMBOL_server_outgoing_tcp_mss = 444, /* server_outgoing_tcp_mss */ + YYSYMBOL_server_tcp_idle_timeout = 445, /* server_tcp_idle_timeout */ + YYSYMBOL_server_max_reuse_tcp_queries = 446, /* server_max_reuse_tcp_queries */ + YYSYMBOL_server_tcp_reuse_timeout = 447, /* server_tcp_reuse_timeout */ + YYSYMBOL_server_tcp_auth_query_timeout = 448, /* server_tcp_auth_query_timeout */ + YYSYMBOL_server_tcp_keepalive = 449, /* server_tcp_keepalive */ + YYSYMBOL_server_tcp_keepalive_timeout = 450, /* server_tcp_keepalive_timeout */ + YYSYMBOL_server_sock_queue_timeout = 451, /* server_sock_queue_timeout */ + YYSYMBOL_server_tcp_upstream = 452, /* server_tcp_upstream */ + YYSYMBOL_server_udp_upstream_without_downstream = 453, /* server_udp_upstream_without_downstream */ + YYSYMBOL_server_ssl_upstream = 454, /* server_ssl_upstream */ + YYSYMBOL_server_ssl_service_key = 455, /* server_ssl_service_key */ + YYSYMBOL_server_ssl_service_pem = 456, /* server_ssl_service_pem */ + YYSYMBOL_server_ssl_port = 457, /* server_ssl_port */ + YYSYMBOL_server_tls_cert_bundle = 458, /* server_tls_cert_bundle */ + YYSYMBOL_server_tls_win_cert = 459, /* server_tls_win_cert */ + YYSYMBOL_server_tls_additional_port = 460, /* server_tls_additional_port */ + YYSYMBOL_server_tls_ciphers = 461, /* server_tls_ciphers */ + YYSYMBOL_server_tls_ciphersuites = 462, /* server_tls_ciphersuites */ + YYSYMBOL_server_tls_session_ticket_keys = 463, /* server_tls_session_ticket_keys */ + YYSYMBOL_server_tls_use_sni = 464, /* server_tls_use_sni */ + YYSYMBOL_server_https_port = 465, /* server_https_port */ + YYSYMBOL_server_http_endpoint = 466, /* server_http_endpoint */ + YYSYMBOL_server_http_max_streams = 467, /* server_http_max_streams */ + YYSYMBOL_server_http_query_buffer_size = 468, /* server_http_query_buffer_size */ + YYSYMBOL_server_http_response_buffer_size = 469, /* server_http_response_buffer_size */ + YYSYMBOL_server_http_nodelay = 470, /* server_http_nodelay */ + YYSYMBOL_server_http_notls_downstream = 471, /* server_http_notls_downstream */ + YYSYMBOL_server_quic_port = 472, /* server_quic_port */ + YYSYMBOL_server_quic_size = 473, /* server_quic_size */ + YYSYMBOL_server_use_systemd = 474, /* server_use_systemd */ + YYSYMBOL_server_do_daemonize = 475, /* server_do_daemonize */ + YYSYMBOL_server_use_syslog = 476, /* server_use_syslog */ + YYSYMBOL_server_log_time_ascii = 477, /* server_log_time_ascii */ + YYSYMBOL_server_log_time_iso = 478, /* server_log_time_iso */ + YYSYMBOL_server_log_queries = 479, /* server_log_queries */ + YYSYMBOL_server_log_replies = 480, /* server_log_replies */ + YYSYMBOL_server_log_tag_queryreply = 481, /* server_log_tag_queryreply */ + YYSYMBOL_server_log_servfail = 482, /* server_log_servfail */ + YYSYMBOL_server_log_destaddr = 483, /* server_log_destaddr */ + YYSYMBOL_server_log_local_actions = 484, /* server_log_local_actions */ + YYSYMBOL_server_chroot = 485, /* server_chroot */ + YYSYMBOL_server_username = 486, /* server_username */ + YYSYMBOL_server_directory = 487, /* server_directory */ + YYSYMBOL_server_logfile = 488, /* server_logfile */ + YYSYMBOL_server_pidfile = 489, /* server_pidfile */ + YYSYMBOL_server_root_hints = 490, /* server_root_hints */ + YYSYMBOL_server_dlv_anchor_file = 491, /* server_dlv_anchor_file */ + YYSYMBOL_server_dlv_anchor = 492, /* server_dlv_anchor */ + YYSYMBOL_server_auto_trust_anchor_file = 493, /* server_auto_trust_anchor_file */ + YYSYMBOL_server_trust_anchor_file = 494, /* server_trust_anchor_file */ + YYSYMBOL_server_trusted_keys_file = 495, /* server_trusted_keys_file */ + YYSYMBOL_server_trust_anchor = 496, /* server_trust_anchor */ + YYSYMBOL_server_trust_anchor_signaling = 497, /* server_trust_anchor_signaling */ + YYSYMBOL_server_root_key_sentinel = 498, /* server_root_key_sentinel */ + YYSYMBOL_server_domain_insecure = 499, /* server_domain_insecure */ + YYSYMBOL_server_hide_identity = 500, /* server_hide_identity */ + YYSYMBOL_server_hide_version = 501, /* server_hide_version */ + YYSYMBOL_server_hide_trustanchor = 502, /* server_hide_trustanchor */ + YYSYMBOL_server_hide_http_user_agent = 503, /* server_hide_http_user_agent */ + YYSYMBOL_server_identity = 504, /* server_identity */ + YYSYMBOL_server_version = 505, /* server_version */ + YYSYMBOL_server_http_user_agent = 506, /* server_http_user_agent */ + YYSYMBOL_server_nsid = 507, /* server_nsid */ + YYSYMBOL_server_so_rcvbuf = 508, /* server_so_rcvbuf */ + YYSYMBOL_server_so_sndbuf = 509, /* server_so_sndbuf */ + YYSYMBOL_server_so_reuseport = 510, /* server_so_reuseport */ + YYSYMBOL_server_ip_transparent = 511, /* server_ip_transparent */ + YYSYMBOL_server_ip_freebind = 512, /* server_ip_freebind */ + YYSYMBOL_server_ip_dscp = 513, /* server_ip_dscp */ + YYSYMBOL_server_stream_wait_size = 514, /* server_stream_wait_size */ + YYSYMBOL_server_edns_buffer_size = 515, /* server_edns_buffer_size */ + YYSYMBOL_server_msg_buffer_size = 516, /* server_msg_buffer_size */ + YYSYMBOL_server_msg_cache_size = 517, /* server_msg_cache_size */ + YYSYMBOL_server_msg_cache_slabs = 518, /* server_msg_cache_slabs */ + YYSYMBOL_server_num_queries_per_thread = 519, /* server_num_queries_per_thread */ + YYSYMBOL_server_jostle_timeout = 520, /* server_jostle_timeout */ + YYSYMBOL_server_delay_close = 521, /* server_delay_close */ + YYSYMBOL_server_udp_connect = 522, /* server_udp_connect */ + YYSYMBOL_server_unblock_lan_zones = 523, /* server_unblock_lan_zones */ + YYSYMBOL_server_insecure_lan_zones = 524, /* server_insecure_lan_zones */ + YYSYMBOL_server_rrset_cache_size = 525, /* server_rrset_cache_size */ + YYSYMBOL_server_rrset_cache_slabs = 526, /* server_rrset_cache_slabs */ + YYSYMBOL_server_infra_host_ttl = 527, /* server_infra_host_ttl */ + YYSYMBOL_server_infra_lame_ttl = 528, /* server_infra_lame_ttl */ + YYSYMBOL_server_infra_cache_numhosts = 529, /* server_infra_cache_numhosts */ + YYSYMBOL_server_infra_cache_lame_size = 530, /* server_infra_cache_lame_size */ + YYSYMBOL_server_infra_cache_slabs = 531, /* server_infra_cache_slabs */ + YYSYMBOL_server_infra_cache_min_rtt = 532, /* server_infra_cache_min_rtt */ + YYSYMBOL_server_infra_cache_max_rtt = 533, /* server_infra_cache_max_rtt */ + YYSYMBOL_server_infra_keep_probing = 534, /* server_infra_keep_probing */ + YYSYMBOL_server_target_fetch_policy = 535, /* server_target_fetch_policy */ + YYSYMBOL_server_harden_short_bufsize = 536, /* server_harden_short_bufsize */ + YYSYMBOL_server_harden_large_queries = 537, /* server_harden_large_queries */ + YYSYMBOL_server_harden_glue = 538, /* server_harden_glue */ + YYSYMBOL_server_harden_unverified_glue = 539, /* server_harden_unverified_glue */ + YYSYMBOL_server_harden_dnssec_stripped = 540, /* server_harden_dnssec_stripped */ + YYSYMBOL_server_harden_below_nxdomain = 541, /* server_harden_below_nxdomain */ + YYSYMBOL_server_harden_referral_path = 542, /* server_harden_referral_path */ + YYSYMBOL_server_harden_algo_downgrade = 543, /* server_harden_algo_downgrade */ + YYSYMBOL_server_harden_unknown_additional = 544, /* server_harden_unknown_additional */ + YYSYMBOL_server_use_caps_for_id = 545, /* server_use_caps_for_id */ + YYSYMBOL_server_caps_whitelist = 546, /* server_caps_whitelist */ + YYSYMBOL_server_private_address = 547, /* server_private_address */ + YYSYMBOL_server_private_domain = 548, /* server_private_domain */ + YYSYMBOL_server_prefetch = 549, /* server_prefetch */ + YYSYMBOL_server_prefetch_key = 550, /* server_prefetch_key */ + YYSYMBOL_server_deny_any = 551, /* server_deny_any */ + YYSYMBOL_server_unwanted_reply_threshold = 552, /* server_unwanted_reply_threshold */ + YYSYMBOL_server_do_not_query_address = 553, /* server_do_not_query_address */ + YYSYMBOL_server_do_not_query_localhost = 554, /* server_do_not_query_localhost */ + YYSYMBOL_server_access_control = 555, /* server_access_control */ + YYSYMBOL_server_interface_action = 556, /* server_interface_action */ + YYSYMBOL_server_module_conf = 557, /* server_module_conf */ + YYSYMBOL_server_val_override_date = 558, /* server_val_override_date */ + YYSYMBOL_server_val_sig_skew_min = 559, /* server_val_sig_skew_min */ + YYSYMBOL_server_val_sig_skew_max = 560, /* server_val_sig_skew_max */ + YYSYMBOL_server_val_max_restart = 561, /* server_val_max_restart */ + YYSYMBOL_server_cache_max_ttl = 562, /* server_cache_max_ttl */ + YYSYMBOL_server_cache_max_negative_ttl = 563, /* server_cache_max_negative_ttl */ + YYSYMBOL_server_cache_min_negative_ttl = 564, /* server_cache_min_negative_ttl */ + YYSYMBOL_server_cache_min_ttl = 565, /* server_cache_min_ttl */ + YYSYMBOL_server_bogus_ttl = 566, /* server_bogus_ttl */ + YYSYMBOL_server_val_clean_additional = 567, /* server_val_clean_additional */ + YYSYMBOL_server_val_permissive_mode = 568, /* server_val_permissive_mode */ + YYSYMBOL_server_aggressive_nsec = 569, /* server_aggressive_nsec */ + YYSYMBOL_server_ignore_cd_flag = 570, /* server_ignore_cd_flag */ + YYSYMBOL_server_disable_edns_do = 571, /* server_disable_edns_do */ + YYSYMBOL_server_serve_expired = 572, /* server_serve_expired */ + YYSYMBOL_server_serve_expired_ttl = 573, /* server_serve_expired_ttl */ + YYSYMBOL_server_serve_expired_ttl_reset = 574, /* server_serve_expired_ttl_reset */ + YYSYMBOL_server_serve_expired_reply_ttl = 575, /* server_serve_expired_reply_ttl */ + YYSYMBOL_server_serve_expired_client_timeout = 576, /* server_serve_expired_client_timeout */ + YYSYMBOL_server_ede_serve_expired = 577, /* server_ede_serve_expired */ + YYSYMBOL_server_serve_original_ttl = 578, /* server_serve_original_ttl */ + YYSYMBOL_server_fake_dsa = 579, /* server_fake_dsa */ + YYSYMBOL_server_fake_sha1 = 580, /* server_fake_sha1 */ + YYSYMBOL_server_val_log_level = 581, /* server_val_log_level */ + YYSYMBOL_server_val_nsec3_keysize_iterations = 582, /* server_val_nsec3_keysize_iterations */ + YYSYMBOL_server_zonemd_permissive_mode = 583, /* server_zonemd_permissive_mode */ + YYSYMBOL_server_add_holddown = 584, /* server_add_holddown */ + YYSYMBOL_server_del_holddown = 585, /* server_del_holddown */ + YYSYMBOL_server_keep_missing = 586, /* server_keep_missing */ + YYSYMBOL_server_permit_small_holddown = 587, /* server_permit_small_holddown */ + YYSYMBOL_server_key_cache_size = 588, /* server_key_cache_size */ + YYSYMBOL_server_key_cache_slabs = 589, /* server_key_cache_slabs */ + YYSYMBOL_server_neg_cache_size = 590, /* server_neg_cache_size */ + YYSYMBOL_server_local_zone = 591, /* server_local_zone */ + YYSYMBOL_server_local_data = 592, /* server_local_data */ + YYSYMBOL_server_local_data_ptr = 593, /* server_local_data_ptr */ + YYSYMBOL_server_minimal_responses = 594, /* server_minimal_responses */ + YYSYMBOL_server_rrset_roundrobin = 595, /* server_rrset_roundrobin */ + YYSYMBOL_server_unknown_server_time_limit = 596, /* server_unknown_server_time_limit */ + YYSYMBOL_server_discard_timeout = 597, /* server_discard_timeout */ + YYSYMBOL_server_wait_limit = 598, /* server_wait_limit */ + YYSYMBOL_server_wait_limit_cookie = 599, /* server_wait_limit_cookie */ + YYSYMBOL_server_wait_limit_netblock = 600, /* server_wait_limit_netblock */ + YYSYMBOL_server_wait_limit_cookie_netblock = 601, /* server_wait_limit_cookie_netblock */ + YYSYMBOL_server_max_udp_size = 602, /* server_max_udp_size */ + YYSYMBOL_server_dns64_prefix = 603, /* server_dns64_prefix */ + YYSYMBOL_server_dns64_synthall = 604, /* server_dns64_synthall */ + YYSYMBOL_server_dns64_ignore_aaaa = 605, /* server_dns64_ignore_aaaa */ + YYSYMBOL_server_nat64_prefix = 606, /* server_nat64_prefix */ + YYSYMBOL_server_define_tag = 607, /* server_define_tag */ + YYSYMBOL_server_local_zone_tag = 608, /* server_local_zone_tag */ + YYSYMBOL_server_access_control_tag = 609, /* server_access_control_tag */ + YYSYMBOL_server_access_control_tag_action = 610, /* server_access_control_tag_action */ + YYSYMBOL_server_access_control_tag_data = 611, /* server_access_control_tag_data */ + YYSYMBOL_server_local_zone_override = 612, /* server_local_zone_override */ + YYSYMBOL_server_access_control_view = 613, /* server_access_control_view */ + YYSYMBOL_server_interface_tag = 614, /* server_interface_tag */ + YYSYMBOL_server_interface_tag_action = 615, /* server_interface_tag_action */ + YYSYMBOL_server_interface_tag_data = 616, /* server_interface_tag_data */ + YYSYMBOL_server_interface_view = 617, /* server_interface_view */ + YYSYMBOL_server_response_ip_tag = 618, /* server_response_ip_tag */ + YYSYMBOL_server_ip_ratelimit = 619, /* server_ip_ratelimit */ + YYSYMBOL_server_ip_ratelimit_cookie = 620, /* server_ip_ratelimit_cookie */ + YYSYMBOL_server_ratelimit = 621, /* server_ratelimit */ + YYSYMBOL_server_ip_ratelimit_size = 622, /* server_ip_ratelimit_size */ + YYSYMBOL_server_ratelimit_size = 623, /* server_ratelimit_size */ + YYSYMBOL_server_ip_ratelimit_slabs = 624, /* server_ip_ratelimit_slabs */ + YYSYMBOL_server_ratelimit_slabs = 625, /* server_ratelimit_slabs */ + YYSYMBOL_server_ratelimit_for_domain = 626, /* server_ratelimit_for_domain */ + YYSYMBOL_server_ratelimit_below_domain = 627, /* server_ratelimit_below_domain */ + YYSYMBOL_server_ip_ratelimit_factor = 628, /* server_ip_ratelimit_factor */ + YYSYMBOL_server_ratelimit_factor = 629, /* server_ratelimit_factor */ + YYSYMBOL_server_ip_ratelimit_backoff = 630, /* server_ip_ratelimit_backoff */ + YYSYMBOL_server_ratelimit_backoff = 631, /* server_ratelimit_backoff */ + YYSYMBOL_server_outbound_msg_retry = 632, /* server_outbound_msg_retry */ + YYSYMBOL_server_max_sent_count = 633, /* server_max_sent_count */ + YYSYMBOL_server_max_query_restarts = 634, /* server_max_query_restarts */ + YYSYMBOL_server_low_rtt = 635, /* server_low_rtt */ + YYSYMBOL_server_fast_server_num = 636, /* server_fast_server_num */ + YYSYMBOL_server_fast_server_permil = 637, /* server_fast_server_permil */ + YYSYMBOL_server_qname_minimisation = 638, /* server_qname_minimisation */ + YYSYMBOL_server_qname_minimisation_strict = 639, /* server_qname_minimisation_strict */ + YYSYMBOL_server_pad_responses = 640, /* server_pad_responses */ + YYSYMBOL_server_pad_responses_block_size = 641, /* server_pad_responses_block_size */ + YYSYMBOL_server_pad_queries = 642, /* server_pad_queries */ + YYSYMBOL_server_pad_queries_block_size = 643, /* server_pad_queries_block_size */ + YYSYMBOL_server_ipsecmod_enabled = 644, /* server_ipsecmod_enabled */ + YYSYMBOL_server_ipsecmod_ignore_bogus = 645, /* server_ipsecmod_ignore_bogus */ + YYSYMBOL_server_ipsecmod_hook = 646, /* server_ipsecmod_hook */ + YYSYMBOL_server_ipsecmod_max_ttl = 647, /* server_ipsecmod_max_ttl */ + YYSYMBOL_server_ipsecmod_whitelist = 648, /* server_ipsecmod_whitelist */ + YYSYMBOL_server_ipsecmod_strict = 649, /* server_ipsecmod_strict */ + YYSYMBOL_server_edns_client_string = 650, /* server_edns_client_string */ + YYSYMBOL_server_edns_client_string_opcode = 651, /* server_edns_client_string_opcode */ + YYSYMBOL_server_ede = 652, /* server_ede */ + YYSYMBOL_server_dns_error_reporting = 653, /* server_dns_error_reporting */ + YYSYMBOL_server_proxy_protocol_port = 654, /* server_proxy_protocol_port */ + YYSYMBOL_stub_name = 655, /* stub_name */ + YYSYMBOL_stub_host = 656, /* stub_host */ + YYSYMBOL_stub_addr = 657, /* stub_addr */ + YYSYMBOL_stub_first = 658, /* stub_first */ + YYSYMBOL_stub_no_cache = 659, /* stub_no_cache */ + YYSYMBOL_stub_ssl_upstream = 660, /* stub_ssl_upstream */ + YYSYMBOL_stub_tcp_upstream = 661, /* stub_tcp_upstream */ + YYSYMBOL_stub_prime = 662, /* stub_prime */ + YYSYMBOL_forward_name = 663, /* forward_name */ + YYSYMBOL_forward_host = 664, /* forward_host */ + YYSYMBOL_forward_addr = 665, /* forward_addr */ + YYSYMBOL_forward_first = 666, /* forward_first */ + YYSYMBOL_forward_no_cache = 667, /* forward_no_cache */ + YYSYMBOL_forward_ssl_upstream = 668, /* forward_ssl_upstream */ + YYSYMBOL_forward_tcp_upstream = 669, /* forward_tcp_upstream */ + YYSYMBOL_auth_name = 670, /* auth_name */ + YYSYMBOL_auth_zonefile = 671, /* auth_zonefile */ + YYSYMBOL_auth_master = 672, /* auth_master */ + YYSYMBOL_auth_url = 673, /* auth_url */ + YYSYMBOL_auth_allow_notify = 674, /* auth_allow_notify */ + YYSYMBOL_auth_zonemd_check = 675, /* auth_zonemd_check */ + YYSYMBOL_auth_zonemd_reject_absence = 676, /* auth_zonemd_reject_absence */ + YYSYMBOL_auth_for_downstream = 677, /* auth_for_downstream */ + YYSYMBOL_auth_for_upstream = 678, /* auth_for_upstream */ + YYSYMBOL_auth_fallback_enabled = 679, /* auth_fallback_enabled */ + YYSYMBOL_view_name = 680, /* view_name */ + YYSYMBOL_view_local_zone = 681, /* view_local_zone */ + YYSYMBOL_view_response_ip = 682, /* view_response_ip */ + YYSYMBOL_view_response_ip_data = 683, /* view_response_ip_data */ + YYSYMBOL_view_local_data = 684, /* view_local_data */ + YYSYMBOL_view_local_data_ptr = 685, /* view_local_data_ptr */ + YYSYMBOL_view_first = 686, /* view_first */ + YYSYMBOL_rcstart = 687, /* rcstart */ + YYSYMBOL_contents_rc = 688, /* contents_rc */ + YYSYMBOL_content_rc = 689, /* content_rc */ + YYSYMBOL_rc_control_enable = 690, /* rc_control_enable */ + YYSYMBOL_rc_control_port = 691, /* rc_control_port */ + YYSYMBOL_rc_control_interface = 692, /* rc_control_interface */ + YYSYMBOL_rc_control_use_cert = 693, /* rc_control_use_cert */ + YYSYMBOL_rc_server_key_file = 694, /* rc_server_key_file */ + YYSYMBOL_rc_server_cert_file = 695, /* rc_server_cert_file */ + YYSYMBOL_rc_control_key_file = 696, /* rc_control_key_file */ + YYSYMBOL_rc_control_cert_file = 697, /* rc_control_cert_file */ + YYSYMBOL_dtstart = 698, /* dtstart */ + YYSYMBOL_contents_dt = 699, /* contents_dt */ + YYSYMBOL_content_dt = 700, /* content_dt */ + YYSYMBOL_dt_dnstap_enable = 701, /* dt_dnstap_enable */ + YYSYMBOL_dt_dnstap_bidirectional = 702, /* dt_dnstap_bidirectional */ + YYSYMBOL_dt_dnstap_socket_path = 703, /* dt_dnstap_socket_path */ + YYSYMBOL_dt_dnstap_ip = 704, /* dt_dnstap_ip */ + YYSYMBOL_dt_dnstap_tls = 705, /* dt_dnstap_tls */ + YYSYMBOL_dt_dnstap_tls_server_name = 706, /* dt_dnstap_tls_server_name */ + YYSYMBOL_dt_dnstap_tls_cert_bundle = 707, /* dt_dnstap_tls_cert_bundle */ + YYSYMBOL_dt_dnstap_tls_client_key_file = 708, /* dt_dnstap_tls_client_key_file */ + YYSYMBOL_dt_dnstap_tls_client_cert_file = 709, /* dt_dnstap_tls_client_cert_file */ + YYSYMBOL_dt_dnstap_send_identity = 710, /* dt_dnstap_send_identity */ + YYSYMBOL_dt_dnstap_send_version = 711, /* dt_dnstap_send_version */ + YYSYMBOL_dt_dnstap_identity = 712, /* dt_dnstap_identity */ + YYSYMBOL_dt_dnstap_version = 713, /* dt_dnstap_version */ + YYSYMBOL_dt_dnstap_log_resolver_query_messages = 714, /* dt_dnstap_log_resolver_query_messages */ + YYSYMBOL_dt_dnstap_log_resolver_response_messages = 715, /* dt_dnstap_log_resolver_response_messages */ + YYSYMBOL_dt_dnstap_log_client_query_messages = 716, /* dt_dnstap_log_client_query_messages */ + YYSYMBOL_dt_dnstap_log_client_response_messages = 717, /* dt_dnstap_log_client_response_messages */ + YYSYMBOL_dt_dnstap_log_forwarder_query_messages = 718, /* dt_dnstap_log_forwarder_query_messages */ + YYSYMBOL_dt_dnstap_log_forwarder_response_messages = 719, /* dt_dnstap_log_forwarder_response_messages */ + YYSYMBOL_dt_dnstap_sample_rate = 720, /* dt_dnstap_sample_rate */ + YYSYMBOL_pythonstart = 721, /* pythonstart */ + YYSYMBOL_contents_py = 722, /* contents_py */ + YYSYMBOL_content_py = 723, /* content_py */ + YYSYMBOL_py_script = 724, /* py_script */ + YYSYMBOL_dynlibstart = 725, /* dynlibstart */ + YYSYMBOL_contents_dl = 726, /* contents_dl */ + YYSYMBOL_content_dl = 727, /* content_dl */ + YYSYMBOL_dl_file = 728, /* dl_file */ + YYSYMBOL_server_disable_dnssec_lame_check = 729, /* server_disable_dnssec_lame_check */ + YYSYMBOL_server_log_identity = 730, /* server_log_identity */ + YYSYMBOL_server_response_ip = 731, /* server_response_ip */ + YYSYMBOL_server_response_ip_data = 732, /* server_response_ip_data */ + YYSYMBOL_dnscstart = 733, /* dnscstart */ + YYSYMBOL_contents_dnsc = 734, /* contents_dnsc */ + YYSYMBOL_content_dnsc = 735, /* content_dnsc */ + YYSYMBOL_dnsc_dnscrypt_enable = 736, /* dnsc_dnscrypt_enable */ + YYSYMBOL_dnsc_dnscrypt_port = 737, /* dnsc_dnscrypt_port */ + YYSYMBOL_dnsc_dnscrypt_provider = 738, /* dnsc_dnscrypt_provider */ + YYSYMBOL_dnsc_dnscrypt_provider_cert = 739, /* dnsc_dnscrypt_provider_cert */ + YYSYMBOL_dnsc_dnscrypt_provider_cert_rotated = 740, /* dnsc_dnscrypt_provider_cert_rotated */ + YYSYMBOL_dnsc_dnscrypt_secret_key = 741, /* dnsc_dnscrypt_secret_key */ + YYSYMBOL_dnsc_dnscrypt_shared_secret_cache_size = 742, /* dnsc_dnscrypt_shared_secret_cache_size */ + YYSYMBOL_dnsc_dnscrypt_shared_secret_cache_slabs = 743, /* dnsc_dnscrypt_shared_secret_cache_slabs */ + YYSYMBOL_dnsc_dnscrypt_nonce_cache_size = 744, /* dnsc_dnscrypt_nonce_cache_size */ + YYSYMBOL_dnsc_dnscrypt_nonce_cache_slabs = 745, /* dnsc_dnscrypt_nonce_cache_slabs */ + YYSYMBOL_cachedbstart = 746, /* cachedbstart */ + YYSYMBOL_contents_cachedb = 747, /* contents_cachedb */ + YYSYMBOL_content_cachedb = 748, /* content_cachedb */ + YYSYMBOL_cachedb_backend_name = 749, /* cachedb_backend_name */ + YYSYMBOL_cachedb_secret_seed = 750, /* cachedb_secret_seed */ + YYSYMBOL_cachedb_no_store = 751, /* cachedb_no_store */ + YYSYMBOL_cachedb_check_when_serve_expired = 752, /* cachedb_check_when_serve_expired */ + YYSYMBOL_redis_server_host = 753, /* redis_server_host */ + YYSYMBOL_redis_replica_server_host = 754, /* redis_replica_server_host */ + YYSYMBOL_redis_server_port = 755, /* redis_server_port */ + YYSYMBOL_redis_replica_server_port = 756, /* redis_replica_server_port */ + YYSYMBOL_redis_server_path = 757, /* redis_server_path */ + YYSYMBOL_redis_replica_server_path = 758, /* redis_replica_server_path */ + YYSYMBOL_redis_server_password = 759, /* redis_server_password */ + YYSYMBOL_redis_replica_server_password = 760, /* redis_replica_server_password */ + YYSYMBOL_redis_timeout = 761, /* redis_timeout */ + YYSYMBOL_redis_replica_timeout = 762, /* redis_replica_timeout */ + YYSYMBOL_redis_command_timeout = 763, /* redis_command_timeout */ + YYSYMBOL_redis_replica_command_timeout = 764, /* redis_replica_command_timeout */ + YYSYMBOL_redis_connect_timeout = 765, /* redis_connect_timeout */ + YYSYMBOL_redis_replica_connect_timeout = 766, /* redis_replica_connect_timeout */ + YYSYMBOL_redis_expire_records = 767, /* redis_expire_records */ + YYSYMBOL_redis_logical_db = 768, /* redis_logical_db */ + YYSYMBOL_redis_replica_logical_db = 769, /* redis_replica_logical_db */ + YYSYMBOL_server_tcp_connection_limit = 770, /* server_tcp_connection_limit */ + YYSYMBOL_server_answer_cookie = 771, /* server_answer_cookie */ + YYSYMBOL_server_cookie_secret = 772, /* server_cookie_secret */ + YYSYMBOL_server_cookie_secret_file = 773, /* server_cookie_secret_file */ + YYSYMBOL_server_iter_scrub_ns = 774, /* server_iter_scrub_ns */ + YYSYMBOL_server_iter_scrub_cname = 775, /* server_iter_scrub_cname */ + YYSYMBOL_server_max_global_quota = 776, /* server_max_global_quota */ + YYSYMBOL_ipsetstart = 777, /* ipsetstart */ + YYSYMBOL_contents_ipset = 778, /* contents_ipset */ + YYSYMBOL_content_ipset = 779, /* content_ipset */ + YYSYMBOL_ipset_name_v4 = 780, /* ipset_name_v4 */ + YYSYMBOL_ipset_name_v6 = 781 /* ipset_name_v6 */ }; typedef enum yysymbol_kind_t yysymbol_kind_t; @@ -1211,19 +1229,19 @@ union yyalloc /* YYFINAL -- State number of the termination state. */ #define YYFINAL 2 /* YYLAST -- Last index in YYTABLE. */ -#define YYLAST 786 +#define YYLAST 805 /* YYNTOKENS -- Number of terminals. */ -#define YYNTOKENS 368 +#define YYNTOKENS 377 /* YYNNTS -- Number of nonterminals. */ -#define YYNNTS 396 +#define YYNNTS 405 /* YYNRULES -- Number of rules. */ -#define YYNRULES 766 +#define YYNRULES 784 /* YYNSTATES -- Number of states. */ -#define YYNSTATES 1147 +#define YYNSTATES 1174 /* YYMAXUTOK -- Last valid token kind. */ -#define YYMAXUTOK 622 +#define YYMAXUTOK 631 /* YYTRANSLATE(TOKEN-NUM) -- Symbol number corresponding to TOKEN-NUM @@ -1299,90 +1317,93 @@ static const yytype_int16 yytranslate[] = 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367 + 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, + 375, 376 }; #if YYDEBUG /* YYRLINE[YYN] -- Source line where rule number YYN was defined. */ static const yytype_int16 yyrline[] = { - 0, 214, 214, 214, 215, 215, 216, 216, 217, 217, - 217, 218, 218, 219, 219, 220, 220, 221, 223, 230, - 236, 237, 238, 238, 238, 239, 239, 240, 240, 240, - 241, 241, 241, 242, 242, 242, 243, 243, 244, 245, - 245, 245, 246, 246, 246, 247, 247, 248, 248, 249, - 249, 250, 250, 251, 251, 252, 252, 253, 253, 254, - 254, 255, 255, 255, 256, 256, 257, 257, 257, 258, - 258, 258, 259, 259, 260, 260, 261, 261, 262, 262, - 263, 263, 263, 264, 264, 265, 265, 266, 266, 266, - 267, 267, 268, 268, 269, 269, 270, 270, 270, 271, - 271, 272, 272, 273, 273, 274, 274, 275, 275, 276, - 276, 277, 277, 278, 278, 279, 279, 279, 280, 280, - 280, 281, 281, 281, 282, 282, 282, 282, 283, 284, - 284, 284, 285, 285, 285, 286, 286, 287, 287, 288, - 288, 288, 289, 289, 289, 290, 290, 291, 291, 291, - 292, 293, 293, 293, 294, 294, 294, 295, 295, 296, - 296, 297, 297, 298, 299, 299, 300, 300, 301, 301, - 302, 302, 303, 303, 304, 304, 305, 305, 306, 306, - 307, 307, 308, 308, 309, 310, 310, 311, 311, 311, - 312, 312, 313, 313, 314, 314, 315, 315, 315, 316, - 316, 317, 318, 318, 319, 319, 320, 321, 321, 322, - 322, 323, 323, 323, 324, 324, 325, 325, 325, 326, - 326, 326, 327, 327, 328, 329, 329, 330, 330, 331, - 331, 332, 332, 333, 333, 333, 334, 334, 334, 335, - 335, 335, 336, 336, 337, 337, 337, 338, 338, 339, - 339, 340, 340, 341, 341, 341, 342, 342, 343, 343, - 344, 344, 345, 345, 346, 346, 347, 347, 348, 348, - 349, 349, 350, 350, 351, 351, 351, 352, 352, 354, - 362, 376, 377, 378, 378, 378, 378, 378, 379, 379, - 379, 381, 389, 403, 404, 405, 405, 405, 405, 406, - 406, 406, 408, 416, 430, 431, 432, 432, 432, 432, - 433, 433, 433, 435, 456, 457, 458, 458, 458, 458, - 459, 459, 459, 460, 460, 460, 463, 482, 499, 507, - 517, 524, 534, 553, 554, 555, 555, 555, 555, 555, - 556, 556, 556, 557, 557, 557, 557, 559, 568, 577, - 588, 597, 606, 615, 624, 635, 644, 656, 670, 685, - 696, 713, 730, 747, 764, 779, 794, 807, 822, 831, - 840, 849, 858, 867, 876, 883, 892, 901, 910, 919, - 928, 937, 946, 955, 964, 977, 988, 999, 1010, 1019, - 1032, 1045, 1054, 1063, 1072, 1079, 1086, 1095, 1102, 1111, - 1119, 1126, 1133, 1141, 1150, 1158, 1174, 1182, 1190, 1198, - 1206, 1214, 1227, 1234, 1243, 1252, 1266, 1275, 1284, 1293, - 1302, 1311, 1320, 1329, 1338, 1345, 1352, 1378, 1386, 1393, - 1400, 1407, 1414, 1422, 1430, 1438, 1445, 1456, 1467, 1474, - 1483, 1492, 1501, 1510, 1517, 1524, 1531, 1547, 1555, 1563, - 1573, 1583, 1593, 1607, 1615, 1628, 1639, 1647, 1660, 1669, - 1678, 1687, 1696, 1706, 1716, 1724, 1737, 1746, 1754, 1763, - 1771, 1784, 1793, 1802, 1812, 1819, 1829, 1839, 1849, 1859, - 1869, 1879, 1889, 1899, 1909, 1919, 1926, 1933, 1940, 1949, - 1958, 1967, 1976, 1983, 1993, 2001, 2010, 2017, 2035, 2048, - 2061, 2074, 2083, 2092, 2101, 2110, 2119, 2129, 2139, 2150, - 2159, 2168, 2177, 2186, 2195, 2204, 2213, 2222, 2231, 2244, - 2257, 2266, 2273, 2282, 2291, 2300, 2309, 2319, 2327, 2340, - 2348, 2404, 2411, 2426, 2436, 2446, 2453, 2460, 2467, 2474, - 2489, 2504, 2511, 2518, 2527, 2535, 2542, 2556, 2577, 2598, - 2610, 2622, 2634, 2643, 2664, 2676, 2688, 2697, 2718, 2727, - 2736, 2745, 2753, 2761, 2774, 2787, 2802, 2817, 2826, 2835, - 2845, 2855, 2864, 2873, 2882, 2888, 2897, 2906, 2916, 2926, - 2936, 2945, 2955, 2964, 2977, 2990, 3002, 3016, 3028, 3042, - 3051, 3062, 3071, 3078, 3088, 3095, 3102, 3111, 3120, 3130, - 3140, 3150, 3160, 3167, 3174, 3183, 3192, 3202, 3212, 3222, - 3229, 3236, 3243, 3251, 3261, 3271, 3281, 3291, 3301, 3311, - 3367, 3377, 3385, 3393, 3408, 3417, 3423, 3424, 3425, 3425, - 3425, 3426, 3426, 3426, 3427, 3427, 3429, 3439, 3448, 3455, - 3462, 3469, 3476, 3483, 3490, 3496, 3497, 3498, 3498, 3498, - 3499, 3499, 3499, 3500, 3501, 3501, 3502, 3502, 3503, 3503, - 3504, 3505, 3506, 3507, 3508, 3509, 3510, 3512, 3521, 3531, - 3538, 3545, 3554, 3561, 3568, 3575, 3582, 3591, 3600, 3607, - 3614, 3624, 3634, 3644, 3654, 3664, 3674, 3685, 3691, 3692, - 3693, 3695, 3702, 3708, 3709, 3710, 3712, 3719, 3729, 3736, - 3745, 3753, 3759, 3760, 3762, 3762, 3762, 3763, 3763, 3764, - 3765, 3766, 3767, 3768, 3770, 3779, 3788, 3795, 3804, 3811, - 3820, 3828, 3841, 3849, 3862, 3868, 3869, 3870, 3870, 3871, - 3871, 3871, 3872, 3872, 3872, 3873, 3873, 3873, 3874, 3874, - 3876, 3888, 3900, 3913, 3926, 3938, 3953, 3965, 3977, 3990, - 4003, 4016, 4029, 4044, 4055, 4064, 4080, 4087, 4096, 4105, - 4114, 4120, 4121, 4122, 4122, 4124, 4139 + 0, 220, 220, 220, 221, 221, 222, 222, 223, 223, + 223, 224, 224, 225, 225, 226, 226, 227, 229, 236, + 242, 243, 244, 244, 244, 245, 245, 246, 246, 246, + 247, 247, 247, 248, 248, 248, 249, 249, 250, 251, + 251, 251, 252, 252, 252, 253, 253, 254, 254, 255, + 255, 256, 256, 257, 257, 258, 258, 259, 259, 260, + 260, 261, 261, 261, 262, 262, 263, 263, 263, 264, + 264, 264, 265, 265, 266, 266, 267, 267, 268, 268, + 269, 269, 269, 270, 270, 271, 271, 272, 272, 272, + 273, 273, 274, 274, 275, 275, 276, 276, 276, 277, + 277, 278, 278, 279, 279, 280, 280, 281, 281, 282, + 282, 283, 283, 284, 284, 285, 285, 285, 286, 286, + 286, 287, 287, 287, 288, 288, 288, 288, 289, 290, + 290, 290, 291, 291, 291, 292, 292, 293, 293, 294, + 294, 294, 295, 295, 295, 296, 296, 297, 297, 297, + 298, 299, 299, 299, 300, 300, 300, 301, 301, 302, + 302, 303, 303, 304, 305, 305, 306, 306, 307, 307, + 308, 308, 309, 309, 310, 310, 311, 311, 312, 312, + 313, 313, 314, 314, 315, 316, 316, 317, 317, 317, + 318, 318, 319, 319, 320, 320, 321, 321, 321, 322, + 322, 323, 324, 324, 325, 325, 326, 327, 327, 328, + 328, 329, 329, 329, 330, 330, 331, 331, 331, 332, + 332, 332, 333, 333, 334, 335, 335, 336, 336, 337, + 337, 338, 338, 339, 339, 339, 340, 340, 340, 341, + 341, 341, 342, 342, 343, 343, 343, 344, 344, 345, + 345, 346, 346, 347, 347, 347, 348, 348, 349, 349, + 350, 350, 351, 351, 352, 352, 353, 353, 354, 355, + 355, 356, 356, 357, 357, 358, 358, 358, 359, 359, + 361, 369, 383, 384, 385, 385, 385, 385, 385, 386, + 386, 386, 388, 396, 410, 411, 412, 412, 412, 412, + 413, 413, 413, 415, 423, 437, 438, 439, 439, 439, + 439, 440, 440, 440, 442, 463, 464, 465, 465, 465, + 465, 466, 466, 466, 467, 467, 467, 470, 489, 506, + 514, 524, 531, 541, 560, 561, 562, 562, 562, 562, + 562, 563, 563, 563, 564, 564, 564, 564, 566, 575, + 584, 595, 604, 613, 622, 631, 642, 651, 663, 677, + 692, 703, 720, 737, 754, 771, 786, 801, 814, 829, + 838, 847, 856, 865, 874, 883, 890, 899, 908, 917, + 926, 935, 944, 953, 962, 971, 984, 995, 1006, 1017, + 1026, 1039, 1052, 1061, 1070, 1079, 1086, 1093, 1102, 1109, + 1118, 1126, 1133, 1140, 1148, 1157, 1165, 1181, 1189, 1197, + 1205, 1213, 1221, 1234, 1241, 1250, 1259, 1273, 1282, 1291, + 1300, 1309, 1318, 1327, 1336, 1345, 1352, 1359, 1385, 1393, + 1400, 1407, 1414, 1421, 1429, 1437, 1445, 1452, 1463, 1474, + 1481, 1490, 1499, 1508, 1517, 1524, 1531, 1538, 1554, 1562, + 1570, 1580, 1590, 1600, 1614, 1622, 1635, 1646, 1654, 1667, + 1676, 1685, 1694, 1703, 1713, 1723, 1731, 1744, 1753, 1761, + 1770, 1778, 1791, 1800, 1809, 1819, 1826, 1836, 1846, 1856, + 1866, 1876, 1886, 1896, 1906, 1916, 1926, 1933, 1940, 1947, + 1956, 1965, 1974, 1983, 1990, 2000, 2008, 2017, 2024, 2042, + 2055, 2068, 2081, 2090, 2099, 2108, 2117, 2126, 2136, 2146, + 2157, 2166, 2175, 2184, 2193, 2202, 2211, 2220, 2229, 2238, + 2251, 2264, 2273, 2280, 2289, 2298, 2307, 2316, 2326, 2334, + 2347, 2355, 2411, 2418, 2433, 2443, 2453, 2460, 2467, 2474, + 2481, 2496, 2511, 2518, 2525, 2534, 2542, 2549, 2563, 2584, + 2605, 2617, 2629, 2641, 2650, 2671, 2683, 2695, 2704, 2725, + 2734, 2743, 2752, 2760, 2768, 2781, 2794, 2809, 2824, 2833, + 2842, 2852, 2862, 2871, 2880, 2889, 2895, 2904, 2913, 2923, + 2933, 2943, 2952, 2962, 2971, 2984, 2997, 3009, 3023, 3035, + 3049, 3058, 3069, 3078, 3087, 3094, 3104, 3111, 3118, 3127, + 3136, 3146, 3156, 3166, 3176, 3183, 3190, 3199, 3208, 3218, + 3228, 3238, 3245, 3252, 3259, 3267, 3277, 3287, 3297, 3307, + 3317, 3327, 3383, 3393, 3401, 3409, 3424, 3433, 3439, 3440, + 3441, 3441, 3441, 3442, 3442, 3442, 3443, 3443, 3445, 3455, + 3464, 3471, 3478, 3485, 3492, 3499, 3506, 3512, 3513, 3514, + 3514, 3514, 3515, 3515, 3515, 3516, 3517, 3517, 3518, 3518, + 3519, 3519, 3520, 3521, 3522, 3523, 3524, 3525, 3526, 3528, + 3537, 3547, 3554, 3561, 3570, 3577, 3584, 3591, 3598, 3607, + 3616, 3623, 3630, 3640, 3650, 3660, 3670, 3680, 3690, 3701, + 3707, 3708, 3709, 3711, 3718, 3724, 3725, 3726, 3728, 3735, + 3745, 3752, 3761, 3769, 3775, 3776, 3778, 3778, 3778, 3779, + 3779, 3780, 3781, 3782, 3783, 3784, 3786, 3795, 3804, 3811, + 3820, 3827, 3836, 3844, 3857, 3865, 3878, 3884, 3885, 3886, + 3886, 3887, 3887, 3888, 3888, 3889, 3889, 3890, 3890, 3891, + 3891, 3892, 3892, 3893, 3893, 3894, 3894, 3895, 3895, 3896, + 3898, 3910, 3922, 3935, 3948, 3960, 3972, 3987, 4002, 4014, + 4026, 4038, 4050, 4063, 4076, 4089, 4102, 4115, 4128, 4141, + 4156, 4171, 4182, 4191, 4207, 4214, 4223, 4232, 4241, 4247, + 4248, 4249, 4249, 4251, 4266 }; #endif @@ -1509,10 +1530,16 @@ static const char *const yytname[] = "VAR_IPSECMOD_HOOK", "VAR_IPSECMOD_IGNORE_BOGUS", "VAR_IPSECMOD_MAX_TTL", "VAR_IPSECMOD_WHITELIST", "VAR_IPSECMOD_STRICT", "VAR_CACHEDB", "VAR_CACHEDB_BACKEND", "VAR_CACHEDB_SECRETSEED", "VAR_CACHEDB_REDISHOST", - "VAR_CACHEDB_REDISPORT", "VAR_CACHEDB_REDISTIMEOUT", - "VAR_CACHEDB_REDISEXPIRERECORDS", "VAR_CACHEDB_REDISPATH", - "VAR_CACHEDB_REDISPASSWORD", "VAR_CACHEDB_REDISLOGICALDB", - "VAR_CACHEDB_REDISCOMMANDTIMEOUT", "VAR_CACHEDB_REDISCONNECTTIMEOUT", + "VAR_CACHEDB_REDISREPLICAHOST", "VAR_CACHEDB_REDISPORT", + "VAR_CACHEDB_REDISREPLICAPORT", "VAR_CACHEDB_REDISTIMEOUT", + "VAR_CACHEDB_REDISREPLICATIMEOUT", "VAR_CACHEDB_REDISEXPIRERECORDS", + "VAR_CACHEDB_REDISPATH", "VAR_CACHEDB_REDISREPLICAPATH", + "VAR_CACHEDB_REDISPASSWORD", "VAR_CACHEDB_REDISREPLICAPASSWORD", + "VAR_CACHEDB_REDISLOGICALDB", "VAR_CACHEDB_REDISREPLICALOGICALDB", + "VAR_CACHEDB_REDISCOMMANDTIMEOUT", + "VAR_CACHEDB_REDISREPLICACOMMANDTIMEOUT", + "VAR_CACHEDB_REDISCONNECTTIMEOUT", + "VAR_CACHEDB_REDISREPLICACONNECTTIMEOUT", "VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM", "VAR_FOR_UPSTREAM", "VAR_AUTH_ZONE", "VAR_ZONEFILE", "VAR_MASTER", "VAR_URL", "VAR_FOR_DOWNSTREAM", "VAR_FALLBACK_ENABLED", "VAR_TLS_ADDITIONAL_PORT", @@ -1532,12 +1559,12 @@ static const char *const yytname[] = "VAR_EDNS_CLIENT_STRING", "VAR_EDNS_CLIENT_STRING_OPCODE", "VAR_NSID", "VAR_ZONEMD_PERMISSIVE_MODE", "VAR_ZONEMD_CHECK", "VAR_ZONEMD_REJECT_ABSENCE", "VAR_RPZ_SIGNAL_NXDOMAIN_RA", - "VAR_INTERFACE_AUTOMATIC_PORTS", "VAR_EDE", "VAR_INTERFACE_ACTION", - "VAR_INTERFACE_VIEW", "VAR_INTERFACE_TAG", "VAR_INTERFACE_TAG_ACTION", - "VAR_INTERFACE_TAG_DATA", "VAR_QUIC_PORT", "VAR_QUIC_SIZE", - "VAR_PROXY_PROTOCOL_PORT", "VAR_STATISTICS_INHIBIT_ZERO", - "VAR_HARDEN_UNKNOWN_ADDITIONAL", "VAR_DISABLE_EDNS_DO", - "VAR_CACHEDB_NO_STORE", "VAR_LOG_DESTADDR", + "VAR_INTERFACE_AUTOMATIC_PORTS", "VAR_EDE", "VAR_DNS_ERROR_REPORTING", + "VAR_INTERFACE_ACTION", "VAR_INTERFACE_VIEW", "VAR_INTERFACE_TAG", + "VAR_INTERFACE_TAG_ACTION", "VAR_INTERFACE_TAG_DATA", "VAR_QUIC_PORT", + "VAR_QUIC_SIZE", "VAR_PROXY_PROTOCOL_PORT", + "VAR_STATISTICS_INHIBIT_ZERO", "VAR_HARDEN_UNKNOWN_ADDITIONAL", + "VAR_DISABLE_EDNS_DO", "VAR_CACHEDB_NO_STORE", "VAR_LOG_DESTADDR", "VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED", "VAR_COOKIE_SECRET_FILE", "VAR_ITER_SCRUB_NS", "VAR_ITER_SCRUB_CNAME", "VAR_MAX_GLOBAL_QUOTA", "VAR_HARDEN_UNVERIFIED_GLUE", "VAR_LOG_TIME_ISO", "$accept", @@ -1657,17 +1684,17 @@ static const char *const yytname[] = "server_ipsecmod_max_ttl", "server_ipsecmod_whitelist", "server_ipsecmod_strict", "server_edns_client_string", "server_edns_client_string_opcode", "server_ede", - "server_proxy_protocol_port", "stub_name", "stub_host", "stub_addr", - "stub_first", "stub_no_cache", "stub_ssl_upstream", "stub_tcp_upstream", - "stub_prime", "forward_name", "forward_host", "forward_addr", - "forward_first", "forward_no_cache", "forward_ssl_upstream", - "forward_tcp_upstream", "auth_name", "auth_zonefile", "auth_master", - "auth_url", "auth_allow_notify", "auth_zonemd_check", - "auth_zonemd_reject_absence", "auth_for_downstream", "auth_for_upstream", - "auth_fallback_enabled", "view_name", "view_local_zone", - "view_response_ip", "view_response_ip_data", "view_local_data", - "view_local_data_ptr", "view_first", "rcstart", "contents_rc", - "content_rc", "rc_control_enable", "rc_control_port", + "server_dns_error_reporting", "server_proxy_protocol_port", "stub_name", + "stub_host", "stub_addr", "stub_first", "stub_no_cache", + "stub_ssl_upstream", "stub_tcp_upstream", "stub_prime", "forward_name", + "forward_host", "forward_addr", "forward_first", "forward_no_cache", + "forward_ssl_upstream", "forward_tcp_upstream", "auth_name", + "auth_zonefile", "auth_master", "auth_url", "auth_allow_notify", + "auth_zonemd_check", "auth_zonemd_reject_absence", "auth_for_downstream", + "auth_for_upstream", "auth_fallback_enabled", "view_name", + "view_local_zone", "view_response_ip", "view_response_ip_data", + "view_local_data", "view_local_data_ptr", "view_first", "rcstart", + "contents_rc", "content_rc", "rc_control_enable", "rc_control_port", "rc_control_interface", "rc_control_use_cert", "rc_server_key_file", "rc_server_cert_file", "rc_control_key_file", "rc_control_cert_file", "dtstart", "contents_dt", "content_dt", "dt_dnstap_enable", @@ -1695,9 +1722,14 @@ static const char *const yytname[] = "cachedbstart", "contents_cachedb", "content_cachedb", "cachedb_backend_name", "cachedb_secret_seed", "cachedb_no_store", "cachedb_check_when_serve_expired", "redis_server_host", - "redis_server_port", "redis_server_path", "redis_server_password", - "redis_timeout", "redis_command_timeout", "redis_connect_timeout", - "redis_expire_records", "redis_logical_db", + "redis_replica_server_host", "redis_server_port", + "redis_replica_server_port", "redis_server_path", + "redis_replica_server_path", "redis_server_password", + "redis_replica_server_password", "redis_timeout", + "redis_replica_timeout", "redis_command_timeout", + "redis_replica_command_timeout", "redis_connect_timeout", + "redis_replica_connect_timeout", "redis_expire_records", + "redis_logical_db", "redis_replica_logical_db", "server_tcp_connection_limit", "server_answer_cookie", "server_cookie_secret", "server_cookie_secret_file", "server_iter_scrub_ns", "server_iter_scrub_cname", @@ -1753,11 +1785,12 @@ static const yytype_int16 yytoknum[] = 585, 586, 587, 588, 589, 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, 613, 614, - 615, 616, 617, 618, 619, 620, 621, 622 + 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, + 625, 626, 627, 628, 629, 630, 631 }; #endif -#define YYPACT_NINF (-302) +#define YYPACT_NINF (-310) #define yypact_value_is_default(Yyn) \ ((Yyn) == YYPACT_NINF) @@ -1771,121 +1804,124 @@ static const yytype_int16 yytoknum[] = STATE-NUM. */ static const yytype_int16 yypact[] = { - -302, 270, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -13, 309, 221, 236, 97, - 84, 148, -14, -81, -301, 182, 122, -294, 31, 32, - 33, 75, 76, 77, 78, 79, 80, 81, 82, 83, - 89, 93, 94, 123, 125, 126, 169, 215, 217, 245, - 246, 247, 259, 261, 262, 263, 264, 265, 268, 269, - 274, 275, 276, 277, 280, 283, 289, 290, 304, 305, - 306, 311, 312, 313, 315, 320, 321, 322, 338, 345, - 347, 350, 351, 352, 353, 354, 356, 359, 361, 362, - 363, 364, 365, 366, 367, 368, 369, 374, 375, 377, - 378, 379, 382, 388, 389, 390, 391, 392, 405, 412, - 413, 414, 415, 416, 417, 418, 422, 423, 424, 425, - 426, 427, 428, 429, 443, 445, 446, 448, 449, 450, - 451, 452, 453, 454, 455, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 467, 468, 469, 470, 472, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, - 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, - 495, 496, 497, 499, 500, 501, 502, 503, 504, 505, - 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, - 516, 517, 518, 519, 521, 522, 524, 525, 526, 527, - 528, 529, 530, 531, 532, 533, 534, 535, 536, 537, - 538, 539, 540, 542, 543, 544, 545, 546, 547, 548, - 549, 550, 551, 552, 553, 554, 556, 557, 558, 559, - 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, - 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, - 580, 581, 582, 583, 584, 585, 586, 588, 589, 590, - 592, 593, 594, 595, 596, 598, 599, 600, 601, 602, - 603, 604, 605, 606, 607, 608, 609, 610, 611, 613, - 614, 615, 616, 617, 618, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, 619, 620, 621, 622, 623, 624, 625, - 626, -302, -302, -302, -302, -302, -302, -302, -302, -302, - 627, 628, 629, 630, 631, 632, 633, -302, -302, -302, - -302, -302, -302, -302, -302, 634, 635, 636, 637, 638, - 639, 640, -302, -302, -302, -302, -302, -302, -302, -302, - 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, 651, 652, 653, 654, 655, 656, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - 657, 658, 659, 660, 661, 662, 663, 664, -302, -302, - -302, -302, -302, -302, -302, -302, -302, 665, 666, 667, - 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, - 678, 679, 680, 681, 682, 683, 684, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, 685, -302, - -302, 686, -302, -302, 687, 688, 689, 690, 691, 692, - 693, 694, 695, 696, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, 697, 698, 699, 700, 701, - 702, 703, 704, 705, 706, 707, 708, 709, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, 710, 711, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, 712, - 713, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, 714, 715, 716, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, 717, 718, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, 719, 720, 721, 722, 723, 724, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, 725, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, 726, 727, -302, -302, -302, -302, -302, - 728, -302, -302, -302, -302, -302, 729, 730, 731, 732, - 733, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - 734, -302, -302, 735, 736, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, 737, 738, 739, -302, - -302, -302, -302, -302, -302, -302, -302, 740, 741, -302, - -302, -302, -302, -302, -302, -302, -302 + -310, 274, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -13, 221, 236, 291, 112, + 88, -14, 292, -81, -309, 142, -121, -302, 31, 32, + 33, 83, 89, 93, 94, 121, 122, 123, 126, 134, + 150, 215, 217, 238, 240, 241, 242, 243, 244, 245, + 246, 247, 259, 262, 263, 265, 266, 267, 268, 269, + 270, 271, 272, 277, 279, 280, 283, 284, 285, 288, + 297, 298, 313, 314, 316, 317, 319, 320, 321, 322, + 329, 330, 345, 347, 354, 355, 357, 358, 360, 361, + 363, 366, 367, 369, 371, 373, 374, 376, 377, 378, + 379, 381, 386, 387, 388, 389, 390, 403, 405, 411, + 412, 413, 414, 415, 417, 423, 424, 425, 426, 427, + 428, 429, 430, 432, 433, 434, 435, 437, 438, 439, + 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, + 450, 451, 452, 477, 478, 479, 480, 481, 482, 483, + 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, + 494, 495, 496, 497, 498, 499, 500, 501, 503, 504, + 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, + 515, 516, 517, 518, 519, 520, 522, 523, 525, 526, + 527, 528, 529, 530, 531, 533, 534, 535, 536, 537, + 538, 539, 540, 541, 542, 543, 544, 547, 548, 549, + 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, + 560, 561, 562, 563, 564, 565, 566, 568, 569, 570, + 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, + 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, + 591, 592, 593, 594, 595, 596, 597, 598, 600, 601, + 602, 604, 605, 606, 607, 608, 610, 611, 612, 613, + 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, + 624, 625, 626, 627, 628, 629, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, 630, 631, 632, 633, 634, + 635, 636, 637, -310, -310, -310, -310, -310, -310, -310, + -310, -310, 638, 639, 640, 641, 642, 643, 644, -310, + -310, -310, -310, -310, -310, -310, -310, 645, 646, 647, + 648, 649, 650, 651, -310, -310, -310, -310, -310, -310, + -310, -310, 652, 653, 654, 655, 656, 657, 658, 659, + 660, 661, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, 662, 663, 664, 665, 666, 667, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, 668, 669, 670, 671, 672, 673, 674, 675, + -310, -310, -310, -310, -310, -310, -310, -310, -310, 676, + 677, 678, 679, 680, 681, 682, 683, 684, 685, 686, + 687, 688, 689, 690, 691, 692, 693, 694, 695, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + 696, -310, -310, 697, -310, -310, 698, 699, 700, 701, + 702, 703, 704, 705, 706, 707, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, 708, 709, 710, + 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, + 721, 722, 723, 724, 725, 726, 727, 728, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + 729, 730, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, 731, 732, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, 733, + 734, 735, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, 736, 737, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, 738, + 739, 740, 741, 742, 743, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + 744, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, 745, 746, -310, -310, -310, -310, -310, 747, -310, + -310, -310, -310, -310, -310, 748, 749, 750, 751, 752, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, 753, + -310, -310, 754, 755, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, 756, 757, 758, -310, -310, -310, -310, + -310, -310, -310, -310, 759, 760, -310, -310, -310, -310, + -310, -310, -310, -310 }; /* YYDEFACT[STATE-NUM] -- Default reduction number in state STATE-NUM. @@ -1893,10 +1929,10 @@ static const yytype_int16 yypact[] = means the default is an error. */ static const yytype_int16 yydefact[] = { - 2, 0, 1, 18, 19, 280, 292, 625, 687, 644, - 303, 701, 724, 313, 760, 332, 692, 3, 17, 21, - 5, 282, 6, 294, 10, 305, 315, 334, 627, 646, - 689, 694, 703, 726, 762, 4, 279, 291, 302, 14, + 2, 0, 1, 18, 19, 281, 293, 627, 689, 646, + 304, 703, 726, 314, 778, 333, 694, 3, 17, 21, + 5, 283, 6, 295, 10, 306, 316, 335, 629, 648, + 691, 696, 705, 728, 780, 4, 280, 292, 303, 14, 15, 8, 9, 7, 16, 11, 12, 13, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, @@ -1923,181 +1959,186 @@ static const yytype_int16 yydefact[] = 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 20, 22, 23, 90, 93, - 102, 269, 219, 220, 24, 172, 173, 174, 175, 176, - 177, 178, 179, 180, 181, 39, 81, 25, 94, 95, - 50, 74, 89, 266, 26, 27, 28, 31, 32, 29, - 30, 33, 34, 35, 261, 262, 263, 36, 37, 38, - 126, 231, 127, 129, 130, 131, 233, 238, 234, 250, - 251, 252, 256, 132, 133, 134, 135, 136, 137, 138, - 264, 265, 215, 91, 80, 106, 278, 124, 125, 243, - 240, 272, 128, 40, 41, 42, 43, 44, 82, 96, - 97, 113, 68, 78, 69, 223, 224, 107, 60, 61, - 222, 64, 62, 63, 65, 259, 117, 121, 142, 154, - 187, 157, 249, 118, 75, 45, 46, 47, 104, 143, - 144, 145, 146, 48, 49, 51, 52, 54, 55, 53, - 151, 152, 158, 56, 57, 58, 66, 277, 85, 122, - 99, 153, 270, 92, 182, 100, 101, 119, 120, 241, - 105, 59, 83, 86, 196, 67, 70, 108, 109, 110, - 84, 183, 184, 111, 71, 72, 73, 232, 123, 271, - 206, 207, 208, 209, 210, 211, 212, 213, 221, 112, - 79, 260, 114, 115, 116, 185, 76, 77, 98, 87, - 88, 103, 139, 140, 242, 244, 245, 246, 247, 248, - 141, 147, 148, 149, 150, 188, 189, 191, 193, 194, - 192, 195, 198, 199, 200, 197, 216, 155, 255, 156, - 161, 162, 159, 160, 163, 164, 166, 165, 168, 167, - 169, 170, 171, 235, 237, 236, 186, 201, 202, 203, - 204, 205, 225, 227, 226, 228, 229, 230, 257, 258, - 267, 268, 190, 214, 217, 218, 239, 253, 254, 273, - 274, 275, 276, 0, 0, 0, 0, 0, 0, 0, - 0, 281, 283, 284, 285, 287, 288, 289, 290, 286, - 0, 0, 0, 0, 0, 0, 0, 293, 295, 296, - 297, 298, 299, 300, 301, 0, 0, 0, 0, 0, - 0, 0, 304, 306, 307, 310, 311, 308, 312, 309, + 0, 0, 0, 0, 0, 0, 20, 22, 23, 90, + 93, 102, 270, 219, 220, 24, 172, 173, 174, 175, + 176, 177, 178, 179, 180, 181, 39, 81, 25, 94, + 95, 50, 74, 89, 266, 26, 27, 28, 31, 32, + 29, 30, 33, 34, 35, 261, 262, 263, 36, 37, + 38, 126, 231, 127, 129, 130, 131, 233, 238, 234, + 250, 251, 252, 256, 132, 133, 134, 135, 136, 137, + 138, 264, 265, 215, 91, 80, 106, 279, 124, 125, + 243, 240, 273, 128, 40, 41, 42, 43, 44, 82, + 96, 97, 113, 68, 78, 69, 223, 224, 107, 60, + 61, 222, 64, 62, 63, 65, 259, 117, 121, 142, + 154, 187, 157, 249, 118, 75, 45, 46, 47, 104, + 143, 144, 145, 146, 48, 49, 51, 52, 54, 55, + 53, 151, 152, 158, 56, 57, 58, 66, 278, 85, + 122, 99, 153, 271, 92, 182, 100, 101, 119, 120, + 241, 105, 59, 83, 86, 196, 67, 70, 108, 109, + 110, 84, 183, 184, 111, 71, 72, 73, 232, 123, + 272, 206, 207, 208, 209, 210, 211, 212, 213, 221, + 112, 79, 260, 114, 115, 116, 185, 76, 77, 98, + 87, 88, 103, 139, 140, 242, 244, 245, 246, 247, + 248, 141, 147, 148, 149, 150, 188, 189, 191, 193, + 194, 192, 195, 198, 199, 200, 197, 216, 155, 255, + 156, 161, 162, 159, 160, 163, 164, 166, 165, 168, + 167, 169, 170, 171, 235, 237, 236, 186, 201, 202, + 203, 204, 205, 225, 227, 226, 228, 229, 230, 257, + 258, 267, 268, 269, 190, 214, 217, 218, 239, 253, + 254, 274, 275, 276, 277, 0, 0, 0, 0, 0, + 0, 0, 0, 282, 284, 285, 286, 288, 289, 290, + 291, 287, 0, 0, 0, 0, 0, 0, 0, 294, + 296, 297, 298, 299, 300, 301, 302, 0, 0, 0, + 0, 0, 0, 0, 305, 307, 308, 311, 312, 309, + 313, 310, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 315, 317, 318, 319, 320, 324, 325, 326, + 321, 322, 323, 0, 0, 0, 0, 0, 0, 338, + 342, 343, 344, 345, 346, 334, 336, 337, 339, 340, + 341, 347, 0, 0, 0, 0, 0, 0, 0, 0, + 628, 630, 632, 631, 637, 633, 634, 635, 636, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 314, 316, 317, 318, 319, 323, 324, 325, 320, 321, - 322, 0, 0, 0, 0, 0, 0, 337, 341, 342, - 343, 344, 345, 333, 335, 336, 338, 339, 340, 346, - 0, 0, 0, 0, 0, 0, 0, 0, 626, 628, - 630, 629, 635, 631, 632, 633, 634, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 647, + 649, 651, 650, 652, 653, 654, 655, 656, 657, 658, + 659, 660, 661, 662, 663, 664, 665, 666, 667, 668, + 0, 690, 692, 0, 695, 697, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 704, 706, 707, 708, + 710, 711, 709, 712, 713, 714, 715, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 645, 647, 649, - 648, 650, 651, 652, 653, 654, 655, 656, 657, 658, - 659, 660, 661, 662, 663, 664, 665, 666, 0, 688, - 690, 0, 693, 695, 0, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 702, 704, 705, 706, 708, 709, - 707, 710, 711, 712, 713, 0, 0, 0, 0, 0, - 0, 0, 0, 0, 0, 0, 0, 0, 725, 727, - 728, 735, 737, 729, 730, 733, 734, 731, 738, 739, - 732, 736, 0, 0, 761, 763, 764, 348, 347, 355, - 368, 366, 380, 375, 376, 377, 381, 378, 379, 382, - 383, 384, 388, 389, 390, 424, 425, 426, 427, 428, - 456, 457, 458, 464, 465, 371, 466, 467, 470, 468, - 469, 474, 475, 476, 492, 439, 440, 443, 444, 477, - 496, 433, 435, 497, 505, 506, 507, 372, 455, 527, - 528, 434, 521, 415, 367, 429, 493, 501, 479, 0, - 0, 531, 373, 349, 414, 484, 350, 369, 370, 430, - 431, 529, 481, 486, 487, 386, 385, 351, 532, 459, - 491, 416, 438, 498, 499, 500, 504, 520, 432, 525, - 523, 524, 447, 454, 488, 489, 448, 449, 480, 509, - 418, 419, 423, 391, 393, 387, 394, 395, 396, 397, - 404, 405, 406, 407, 408, 409, 410, 533, 534, 541, - 460, 461, 462, 463, 471, 472, 473, 542, 543, 544, - 545, 0, 0, 0, 482, 450, 452, 697, 558, 563, - 561, 560, 564, 562, 571, 572, 573, 0, 0, 567, - 568, 569, 570, 356, 357, 358, 359, 360, 361, 362, - 363, 364, 365, 485, 502, 526, 503, 577, 578, 451, - 546, 0, 0, 0, 0, 0, 0, 511, 512, 513, - 514, 515, 516, 517, 518, 519, 698, 441, 442, 445, - 436, 508, 413, 353, 354, 437, 579, 580, 581, 582, - 583, 585, 584, 586, 587, 588, 392, 399, 574, 576, - 575, 398, 0, 754, 755, 559, 421, 490, 535, 420, - 536, 537, 538, 0, 0, 453, 400, 401, 403, 402, - 0, 590, 446, 522, 374, 591, 0, 0, 0, 0, - 0, 411, 412, 592, 352, 483, 510, 422, 756, 757, - 758, 759, 478, 417, 593, 594, 595, 600, 598, 599, - 596, 597, 601, 602, 603, 604, 606, 607, 605, 618, - 0, 622, 623, 0, 0, 624, 608, 616, 609, 610, - 611, 615, 617, 612, 613, 614, 326, 327, 328, 329, - 330, 331, 636, 638, 637, 640, 641, 642, 643, 639, - 667, 669, 670, 671, 672, 673, 674, 675, 676, 677, - 668, 678, 679, 680, 681, 682, 683, 684, 685, 686, - 691, 696, 714, 715, 716, 719, 717, 718, 720, 721, - 722, 723, 740, 741, 744, 745, 748, 751, 746, 747, - 752, 749, 750, 742, 743, 765, 766, 494, 530, 557, - 699, 700, 565, 566, 547, 548, 0, 0, 0, 552, - 753, 539, 540, 589, 495, 556, 553, 0, 0, 619, - 620, 621, 551, 549, 550, 554, 555 + 0, 0, 0, 0, 0, 0, 0, 0, 727, 729, + 730, 747, 749, 731, 732, 733, 734, 741, 742, 743, + 744, 735, 736, 737, 738, 739, 740, 748, 745, 746, + 0, 0, 779, 781, 782, 349, 348, 356, 369, 367, + 381, 376, 377, 378, 382, 379, 380, 383, 384, 385, + 389, 390, 391, 425, 426, 427, 428, 429, 457, 458, + 459, 465, 466, 372, 467, 468, 471, 469, 470, 475, + 476, 477, 493, 440, 441, 444, 445, 478, 497, 434, + 436, 498, 506, 507, 508, 373, 456, 528, 529, 435, + 522, 416, 368, 430, 494, 502, 480, 0, 0, 532, + 374, 350, 415, 485, 351, 370, 371, 431, 432, 530, + 482, 487, 488, 387, 386, 352, 533, 460, 492, 417, + 439, 499, 500, 501, 505, 521, 433, 526, 524, 525, + 448, 455, 489, 490, 449, 450, 481, 510, 419, 420, + 424, 392, 394, 388, 395, 396, 397, 398, 405, 406, + 407, 408, 409, 410, 411, 534, 535, 542, 461, 462, + 463, 464, 472, 473, 474, 543, 544, 545, 546, 0, + 0, 0, 483, 451, 453, 699, 559, 564, 562, 561, + 565, 563, 572, 573, 574, 0, 0, 568, 569, 570, + 571, 357, 358, 359, 360, 361, 362, 363, 364, 365, + 366, 486, 503, 527, 504, 578, 579, 452, 547, 0, + 0, 0, 0, 0, 0, 512, 513, 514, 515, 516, + 517, 518, 519, 520, 700, 442, 443, 446, 437, 509, + 414, 354, 355, 438, 580, 581, 582, 583, 584, 586, + 585, 587, 588, 589, 393, 400, 575, 577, 576, 399, + 0, 772, 773, 560, 422, 491, 536, 421, 537, 538, + 539, 0, 0, 454, 401, 402, 404, 403, 0, 591, + 447, 523, 375, 592, 593, 0, 0, 0, 0, 0, + 412, 413, 594, 353, 484, 511, 423, 774, 775, 776, + 777, 479, 418, 595, 596, 597, 602, 600, 601, 598, + 599, 603, 604, 605, 606, 608, 609, 607, 620, 0, + 624, 625, 0, 0, 626, 610, 618, 611, 612, 613, + 617, 619, 614, 615, 616, 327, 328, 329, 330, 331, + 332, 638, 640, 639, 642, 643, 644, 645, 641, 669, + 671, 672, 673, 674, 675, 676, 677, 678, 679, 670, + 680, 681, 682, 683, 684, 685, 686, 687, 688, 693, + 698, 716, 717, 718, 721, 719, 720, 722, 723, 724, + 725, 750, 751, 754, 755, 756, 757, 762, 763, 768, + 758, 759, 760, 761, 769, 770, 764, 765, 766, 767, + 752, 753, 783, 784, 495, 531, 558, 701, 702, 566, + 567, 548, 549, 0, 0, 0, 553, 771, 540, 541, + 590, 496, 557, 554, 0, 0, 621, 622, 623, 552, + 550, 551, 555, 556 }; /* YYPGOTO[NTERM-NUM]. */ static const yytype_int16 yypgoto[] = { - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, 92, 742, 743, 744, 745, -302, -302, 746, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302, -302, -302, -302, -302, - -302, -302, -302, -302, -302, -302 + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, 261, 761, 762, 763, 764, -310, -310, + 765, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310, -310, -310, -310, -310, -310, + -310, -310, -310, -310, -310 }; /* YYDEFGOTO[NTERM-NUM]. */ static const yytype_int16 yydefgoto[] = { - 0, 1, 17, 18, 19, 35, 305, 20, 21, 36, - 571, 22, 23, 37, 587, 24, 25, 38, 602, 26, - 39, 620, 637, 638, 639, 640, 641, 642, 27, 40, - 643, 306, 307, 308, 309, 310, 311, 312, 313, 314, - 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, - 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, - 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, - 345, 346, 347, 348, 349, 350, 351, 352, 353, 354, - 355, 356, 357, 358, 359, 360, 361, 362, 363, 364, - 365, 366, 367, 368, 369, 370, 371, 372, 373, 374, - 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, - 385, 386, 387, 388, 389, 390, 391, 392, 393, 394, - 395, 396, 397, 398, 399, 400, 401, 402, 403, 404, - 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, - 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, - 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, - 435, 436, 437, 438, 439, 440, 441, 442, 443, 444, - 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, - 455, 456, 457, 458, 459, 460, 461, 462, 463, 464, - 465, 466, 467, 468, 469, 470, 471, 472, 473, 474, - 475, 476, 477, 478, 479, 480, 481, 482, 483, 484, - 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, - 495, 496, 497, 498, 499, 500, 501, 502, 503, 504, - 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, - 515, 516, 517, 518, 519, 520, 521, 522, 523, 524, - 525, 526, 527, 528, 529, 530, 531, 532, 533, 534, - 535, 536, 537, 538, 539, 540, 541, 542, 543, 544, - 545, 546, 547, 548, 549, 550, 551, 572, 573, 574, - 575, 576, 577, 578, 579, 588, 589, 590, 591, 592, - 593, 594, 621, 622, 623, 624, 625, 626, 627, 628, - 629, 630, 603, 604, 605, 606, 607, 608, 609, 28, - 41, 658, 659, 660, 661, 662, 663, 664, 665, 666, - 29, 42, 687, 688, 689, 690, 691, 692, 693, 694, - 695, 696, 697, 698, 699, 700, 701, 702, 703, 704, - 705, 706, 707, 30, 43, 709, 710, 31, 44, 712, - 713, 552, 553, 554, 555, 32, 45, 724, 725, 726, - 727, 728, 729, 730, 731, 732, 733, 734, 33, 46, - 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, - 758, 759, 760, 761, 556, 557, 558, 559, 560, 561, - 562, 34, 47, 764, 765, 766 + 0, 1, 17, 18, 19, 35, 306, 20, 21, 36, + 573, 22, 23, 37, 589, 24, 25, 38, 604, 26, + 39, 622, 639, 640, 641, 642, 643, 644, 27, 40, + 645, 307, 308, 309, 310, 311, 312, 313, 314, 315, + 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, + 326, 327, 328, 329, 330, 331, 332, 333, 334, 335, + 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, + 346, 347, 348, 349, 350, 351, 352, 353, 354, 355, + 356, 357, 358, 359, 360, 361, 362, 363, 364, 365, + 366, 367, 368, 369, 370, 371, 372, 373, 374, 375, + 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, + 396, 397, 398, 399, 400, 401, 402, 403, 404, 405, + 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, + 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, + 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, + 436, 437, 438, 439, 440, 441, 442, 443, 444, 445, + 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, + 456, 457, 458, 459, 460, 461, 462, 463, 464, 465, + 466, 467, 468, 469, 470, 471, 472, 473, 474, 475, + 476, 477, 478, 479, 480, 481, 482, 483, 484, 485, + 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, + 496, 497, 498, 499, 500, 501, 502, 503, 504, 505, + 506, 507, 508, 509, 510, 511, 512, 513, 514, 515, + 516, 517, 518, 519, 520, 521, 522, 523, 524, 525, + 526, 527, 528, 529, 530, 531, 532, 533, 534, 535, + 536, 537, 538, 539, 540, 541, 542, 543, 544, 545, + 546, 547, 548, 549, 550, 551, 552, 553, 574, 575, + 576, 577, 578, 579, 580, 581, 590, 591, 592, 593, + 594, 595, 596, 623, 624, 625, 626, 627, 628, 629, + 630, 631, 632, 605, 606, 607, 608, 609, 610, 611, + 28, 41, 660, 661, 662, 663, 664, 665, 666, 667, + 668, 29, 42, 689, 690, 691, 692, 693, 694, 695, + 696, 697, 698, 699, 700, 701, 702, 703, 704, 705, + 706, 707, 708, 709, 30, 43, 711, 712, 31, 44, + 714, 715, 554, 555, 556, 557, 32, 45, 726, 727, + 728, 729, 730, 731, 732, 733, 734, 735, 736, 33, + 46, 758, 759, 760, 761, 762, 763, 764, 765, 766, + 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, + 777, 778, 779, 558, 559, 560, 561, 562, 563, 564, + 34, 47, 782, 783, 784 }; /* YYTABLE[YYPACT[STATE-NUM]] -- What to do in state STATE-NUM. If @@ -2108,82 +2149,84 @@ static const yytype_int16 yytable[] = 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, - 78, 79, 80, 81, 762, 763, 708, 711, 82, 83, - 84, 767, 768, 769, 85, 86, 87, 88, 89, 90, + 78, 79, 80, 81, 780, 781, 710, 713, 82, 83, + 84, 785, 786, 787, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, - 121, 122, 123, 124, 125, 770, 771, 772, 773, 774, - 775, 776, 777, 778, 126, 127, 128, 129, 130, 779, - 131, 132, 133, 780, 781, 134, 135, 136, 137, 138, + 121, 122, 123, 124, 125, 652, 653, 654, 655, 656, + 657, 658, 659, 788, 126, 127, 128, 129, 130, 789, + 131, 132, 133, 790, 791, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, - 159, 610, 644, 782, 160, 783, 784, 161, 162, 163, - 164, 165, 166, 167, 610, 168, 169, 170, 171, 172, - 173, 174, 175, 176, 177, 178, 179, 180, 181, 667, - 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, - 678, 679, 680, 681, 682, 683, 684, 685, 686, 785, + 159, 792, 793, 794, 160, 612, 795, 161, 162, 163, + 164, 165, 166, 167, 796, 168, 169, 170, 171, 172, + 173, 174, 175, 176, 177, 178, 179, 180, 181, 612, + 797, 737, 738, 739, 740, 741, 742, 743, 744, 745, + 746, 747, 748, 749, 750, 751, 752, 753, 754, 755, 182, 183, 184, 185, 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, - 222, 223, 224, 225, 226, 786, 227, 787, 228, 229, + 222, 223, 224, 225, 226, 798, 227, 799, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 238, 239, - 240, 241, 242, 243, 244, 245, 246, 650, 651, 652, - 653, 654, 655, 656, 657, 788, 789, 790, 247, 248, - 249, 250, 251, 252, 253, 254, 255, 256, 580, 791, - 2, 792, 793, 794, 795, 796, 581, 582, 797, 798, - 257, 3, 4, 595, 799, 800, 801, 802, 258, 259, - 803, 260, 261, 804, 262, 263, 264, 265, 266, 805, - 806, 267, 268, 269, 270, 271, 272, 273, 274, 275, - 276, 277, 278, 279, 807, 808, 809, 280, 5, 596, - 597, 810, 811, 812, 6, 813, 281, 282, 283, 284, - 814, 815, 816, 285, 286, 287, 288, 289, 290, 291, - 292, 293, 294, 295, 296, 297, 598, 298, 817, 299, - 300, 301, 302, 303, 304, 818, 563, 819, 564, 565, - 820, 821, 822, 823, 824, 583, 825, 584, 7, 826, - 585, 827, 828, 829, 830, 831, 832, 833, 834, 835, - 612, 613, 614, 615, 836, 837, 8, 838, 839, 840, - 617, 611, 841, 612, 613, 614, 615, 616, 842, 843, - 844, 845, 846, 617, 735, 736, 737, 738, 739, 740, - 741, 742, 743, 744, 745, 847, 631, 632, 633, 634, - 635, 566, 848, 849, 850, 851, 852, 853, 854, 636, - 599, 600, 855, 856, 857, 858, 859, 860, 861, 862, - 618, 619, 9, 714, 715, 716, 717, 718, 719, 720, - 721, 722, 723, 863, 567, 864, 865, 568, 866, 867, - 868, 869, 870, 871, 872, 873, 569, 874, 875, 876, - 877, 878, 879, 880, 881, 882, 601, 883, 884, 885, - 886, 746, 887, 747, 888, 889, 890, 891, 892, 893, - 894, 895, 896, 897, 898, 899, 900, 901, 902, 903, - 904, 905, 906, 907, 908, 909, 910, 911, 10, 912, + 240, 241, 242, 243, 244, 245, 246, 756, 800, 757, + 801, 802, 803, 804, 805, 806, 807, 808, 247, 248, + 249, 250, 251, 252, 253, 254, 255, 256, 565, 809, + 566, 567, 810, 811, 2, 812, 813, 814, 815, 816, + 817, 818, 819, 582, 0, 3, 4, 820, 257, 821, + 822, 583, 584, 823, 824, 825, 258, 259, 826, 260, + 261, 646, 262, 263, 264, 265, 266, 827, 828, 267, + 268, 269, 270, 271, 272, 273, 274, 275, 276, 277, + 278, 279, 5, 829, 830, 280, 831, 832, 6, 833, + 834, 835, 836, 568, 281, 282, 283, 284, 597, 837, + 838, 285, 286, 287, 288, 289, 290, 291, 292, 293, + 294, 295, 296, 297, 298, 839, 299, 840, 300, 301, + 302, 303, 304, 305, 841, 842, 569, 843, 844, 570, + 845, 846, 7, 847, 598, 599, 848, 849, 571, 850, + 585, 851, 586, 852, 853, 587, 854, 855, 856, 857, + 8, 858, 614, 615, 616, 617, 859, 860, 861, 862, + 863, 600, 619, 716, 717, 718, 719, 720, 721, 722, + 723, 724, 725, 864, 613, 865, 614, 615, 616, 617, + 618, 866, 867, 868, 869, 870, 619, 871, 633, 634, + 635, 636, 637, 872, 873, 874, 875, 876, 877, 878, + 879, 638, 880, 881, 882, 883, 9, 884, 885, 886, + 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, + 897, 898, 899, 620, 621, 669, 670, 671, 672, 673, + 674, 675, 676, 677, 678, 679, 680, 681, 682, 683, + 684, 685, 686, 687, 688, 601, 602, 900, 901, 902, + 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, 919, 920, 921, 922, - 923, 924, 925, 926, 927, 928, 929, 930, 931, 932, - 11, 933, 934, 586, 935, 936, 937, 938, 939, 940, - 941, 942, 943, 944, 945, 946, 947, 948, 949, 950, - 951, 12, 952, 953, 954, 955, 956, 957, 958, 959, - 960, 961, 962, 963, 964, 13, 965, 966, 967, 968, - 969, 970, 971, 972, 973, 974, 975, 976, 977, 978, - 979, 980, 981, 982, 983, 984, 985, 986, 987, 988, - 989, 990, 991, 992, 993, 994, 995, 14, 996, 997, - 998, 15, 999, 1000, 1001, 1002, 1003, 16, 1004, 1005, - 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 1015, - 1016, 1017, 570, 1018, 1019, 1020, 1021, 1022, 1023, 1024, - 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, 1033, 1034, - 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, 1043, 1044, - 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, 1053, 1054, - 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, 1063, 1064, - 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, 1073, 1074, - 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, 1083, 1084, - 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, 1093, 1094, - 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, 1103, 1104, - 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, 1113, 1114, - 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, 1123, 1124, - 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, 1133, 1134, - 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, 1143, 1144, - 1145, 1146, 0, 0, 0, 0, 0, 0, 0, 0, + 923, 924, 10, 925, 926, 927, 928, 929, 930, 931, + 932, 933, 934, 935, 936, 937, 938, 939, 940, 941, + 942, 603, 943, 944, 11, 945, 946, 947, 948, 949, + 950, 951, 572, 952, 953, 954, 955, 956, 957, 958, + 959, 960, 961, 962, 963, 12, 588, 964, 965, 966, + 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, + 977, 978, 979, 980, 981, 982, 983, 13, 984, 985, + 986, 987, 988, 989, 990, 991, 992, 993, 994, 995, + 996, 997, 998, 999, 1000, 1001, 1002, 1003, 1004, 1005, + 1006, 1007, 1008, 1009, 1010, 1011, 1012, 1013, 1014, 14, + 1015, 1016, 1017, 15, 1018, 1019, 1020, 1021, 1022, 16, + 1023, 1024, 1025, 1026, 1027, 1028, 1029, 1030, 1031, 1032, + 1033, 1034, 1035, 1036, 1037, 1038, 1039, 1040, 1041, 1042, + 1043, 1044, 1045, 1046, 1047, 1048, 1049, 1050, 1051, 1052, + 1053, 1054, 1055, 1056, 1057, 1058, 1059, 1060, 1061, 1062, + 1063, 1064, 1065, 1066, 1067, 1068, 1069, 1070, 1071, 1072, + 1073, 1074, 1075, 1076, 1077, 1078, 1079, 1080, 1081, 1082, + 1083, 1084, 1085, 1086, 1087, 1088, 1089, 1090, 1091, 1092, + 1093, 1094, 1095, 1096, 1097, 1098, 1099, 1100, 1101, 1102, + 1103, 1104, 1105, 1106, 1107, 1108, 1109, 1110, 1111, 1112, + 1113, 1114, 1115, 1116, 1117, 1118, 1119, 1120, 1121, 1122, + 1123, 1124, 1125, 1126, 1127, 1128, 1129, 1130, 1131, 1132, + 1133, 1134, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1142, + 1143, 1144, 1145, 1146, 1147, 1148, 1149, 1150, 1151, 1152, + 1153, 1154, 1155, 1156, 1157, 1158, 1159, 1160, 1161, 1162, + 1163, 1164, 1165, 1166, 1167, 1168, 1169, 1170, 1171, 1172, + 1173, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, - 0, 0, 645, 646, 647, 648, 649 + 0, 647, 648, 649, 650, 651 }; static const yytype_int16 yycheck[] = @@ -2191,66 +2234,68 @@ static const yytype_int16 yycheck[] = 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, - 43, 44, 45, 46, 328, 329, 117, 338, 51, 52, + 43, 44, 45, 46, 336, 337, 117, 346, 51, 52, 53, 10, 10, 10, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, - 93, 94, 95, 96, 97, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 107, 108, 109, 110, 111, 10, + 93, 94, 95, 96, 97, 99, 100, 101, 102, 103, + 104, 105, 106, 10, 107, 108, 109, 110, 111, 10, 113, 114, 115, 10, 10, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, - 143, 47, 40, 10, 147, 10, 10, 150, 151, 152, - 153, 154, 155, 156, 47, 158, 159, 160, 161, 162, - 163, 164, 165, 166, 167, 168, 169, 170, 171, 173, - 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, - 184, 185, 186, 187, 188, 189, 190, 191, 192, 10, + 143, 10, 10, 10, 147, 47, 10, 150, 151, 152, + 153, 154, 155, 156, 10, 158, 159, 160, 161, 162, + 163, 164, 165, 166, 167, 168, 169, 170, 171, 47, + 10, 282, 283, 284, 285, 286, 287, 288, 289, 290, + 291, 292, 293, 294, 295, 296, 297, 298, 299, 300, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, 234, 235, 236, 237, 10, 239, 10, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, - 253, 254, 255, 256, 257, 258, 259, 99, 100, 101, - 102, 103, 104, 105, 106, 10, 10, 10, 271, 272, + 253, 254, 255, 256, 257, 258, 259, 368, 10, 370, + 10, 10, 10, 10, 10, 10, 10, 10, 271, 272, 273, 274, 275, 276, 277, 278, 279, 280, 47, 10, - 0, 10, 10, 10, 10, 10, 55, 56, 10, 10, - 293, 11, 12, 47, 10, 10, 10, 10, 301, 302, - 10, 304, 305, 10, 307, 308, 309, 310, 311, 10, - 10, 314, 315, 316, 317, 318, 319, 320, 321, 322, - 323, 324, 325, 326, 10, 10, 10, 330, 48, 83, - 84, 10, 10, 10, 54, 10, 339, 340, 341, 342, - 10, 10, 10, 346, 347, 348, 349, 350, 351, 352, - 353, 354, 355, 356, 357, 358, 110, 360, 10, 362, - 363, 364, 365, 366, 367, 10, 47, 10, 49, 50, - 10, 10, 10, 10, 10, 144, 10, 146, 98, 10, - 149, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 296, 297, 298, 299, 10, 10, 116, 10, 10, 10, - 306, 294, 10, 296, 297, 298, 299, 300, 10, 10, - 10, 10, 10, 306, 282, 283, 284, 285, 286, 287, - 288, 289, 290, 291, 292, 10, 332, 333, 334, 335, - 336, 112, 10, 10, 10, 10, 10, 10, 10, 345, - 194, 195, 10, 10, 10, 10, 10, 10, 10, 10, - 343, 344, 172, 261, 262, 263, 264, 265, 266, 267, - 268, 269, 270, 10, 145, 10, 10, 148, 10, 10, - 10, 10, 10, 10, 10, 10, 157, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 240, 10, 10, 10, - 10, 359, 10, 361, 10, 10, 10, 10, 10, 10, + 49, 50, 10, 10, 0, 10, 10, 10, 10, 10, + 10, 10, 10, 47, -1, 11, 12, 10, 301, 10, + 10, 55, 56, 10, 10, 10, 309, 310, 10, 312, + 313, 40, 315, 316, 317, 318, 319, 10, 10, 322, + 323, 324, 325, 326, 327, 328, 329, 330, 331, 332, + 333, 334, 48, 10, 10, 338, 10, 10, 54, 10, + 10, 10, 10, 112, 347, 348, 349, 350, 47, 10, + 10, 354, 355, 356, 357, 358, 359, 360, 361, 362, + 363, 364, 365, 366, 367, 10, 369, 10, 371, 372, + 373, 374, 375, 376, 10, 10, 145, 10, 10, 148, + 10, 10, 98, 10, 83, 84, 10, 10, 157, 10, + 144, 10, 146, 10, 10, 149, 10, 10, 10, 10, + 116, 10, 304, 305, 306, 307, 10, 10, 10, 10, + 10, 110, 314, 261, 262, 263, 264, 265, 266, 267, + 268, 269, 270, 10, 302, 10, 304, 305, 306, 307, + 308, 10, 10, 10, 10, 10, 314, 10, 340, 341, + 342, 343, 344, 10, 10, 10, 10, 10, 10, 10, + 10, 353, 10, 10, 10, 10, 172, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 351, 352, 173, 174, 175, 176, 177, + 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, + 188, 189, 190, 191, 192, 194, 195, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 238, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 10, 238, 10, + 10, 240, 10, 10, 260, 10, 10, 10, 10, 10, + 10, 10, 321, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 281, 320, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 303, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 260, 10, 10, 312, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 281, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 295, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 335, + 10, 10, 10, 339, 10, 10, 10, 10, 10, 345, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10, 327, 10, 10, - 10, 331, 10, 10, 10, 10, 10, 337, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 313, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, @@ -2263,21 +2308,21 @@ static const yytype_int16 yycheck[] = 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, -1, -1, -1, -1, -1, -1, -1, -1, + 10, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, - -1, -1, 40, 40, 40, 40, 40 + -1, 40, 40, 40, 40, 40 }; /* YYSTOS[STATE-NUM] -- The (internal number of the) accessing symbol of state STATE-NUM. */ static const yytype_int16 yystos[] = { - 0, 369, 0, 11, 12, 48, 54, 98, 116, 172, - 238, 260, 281, 295, 327, 331, 337, 370, 371, 372, - 375, 376, 379, 380, 383, 384, 387, 396, 677, 688, - 711, 715, 723, 736, 759, 373, 377, 381, 385, 388, - 397, 678, 689, 712, 716, 724, 737, 760, 13, 14, + 0, 378, 0, 11, 12, 48, 54, 98, 116, 172, + 238, 260, 281, 303, 335, 339, 345, 379, 380, 381, + 384, 385, 388, 389, 392, 393, 396, 405, 687, 698, + 721, 725, 733, 746, 777, 382, 386, 390, 394, 397, + 406, 688, 699, 722, 726, 734, 747, 778, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, @@ -2298,58 +2343,61 @@ static const yytype_int16 yystos[] = 231, 232, 233, 234, 235, 236, 237, 239, 241, 242, 243, 244, 245, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, 271, 272, 273, - 274, 275, 276, 277, 278, 279, 280, 293, 301, 302, - 304, 305, 307, 308, 309, 310, 311, 314, 315, 316, - 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, - 330, 339, 340, 341, 342, 346, 347, 348, 349, 350, - 351, 352, 353, 354, 355, 356, 357, 358, 360, 362, - 363, 364, 365, 366, 367, 374, 399, 400, 401, 402, - 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, - 413, 414, 415, 416, 417, 418, 419, 420, 421, 422, - 423, 424, 425, 426, 427, 428, 429, 430, 431, 432, - 433, 434, 435, 436, 437, 438, 439, 440, 441, 442, - 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, - 453, 454, 455, 456, 457, 458, 459, 460, 461, 462, - 463, 464, 465, 466, 467, 468, 469, 470, 471, 472, - 473, 474, 475, 476, 477, 478, 479, 480, 481, 482, - 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, - 493, 494, 495, 496, 497, 498, 499, 500, 501, 502, - 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, - 513, 514, 515, 516, 517, 518, 519, 520, 521, 522, - 523, 524, 525, 526, 527, 528, 529, 530, 531, 532, - 533, 534, 535, 536, 537, 538, 539, 540, 541, 542, - 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, - 553, 554, 555, 556, 557, 558, 559, 560, 561, 562, - 563, 564, 565, 566, 567, 568, 569, 570, 571, 572, - 573, 574, 575, 576, 577, 578, 579, 580, 581, 582, - 583, 584, 585, 586, 587, 588, 589, 590, 591, 592, - 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, - 603, 604, 605, 606, 607, 608, 609, 610, 611, 612, - 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, - 623, 624, 625, 626, 627, 628, 629, 630, 631, 632, - 633, 634, 635, 636, 637, 638, 639, 640, 641, 642, - 643, 644, 719, 720, 721, 722, 752, 753, 754, 755, - 756, 757, 758, 47, 49, 50, 112, 145, 148, 157, - 313, 378, 645, 646, 647, 648, 649, 650, 651, 652, - 47, 55, 56, 144, 146, 149, 312, 382, 653, 654, - 655, 656, 657, 658, 659, 47, 83, 84, 110, 194, - 195, 240, 386, 670, 671, 672, 673, 674, 675, 676, - 47, 294, 296, 297, 298, 299, 300, 306, 343, 344, - 389, 660, 661, 662, 663, 664, 665, 666, 667, 668, - 669, 332, 333, 334, 335, 336, 345, 390, 391, 392, - 393, 394, 395, 398, 660, 661, 662, 663, 664, 667, - 99, 100, 101, 102, 103, 104, 105, 106, 679, 680, - 681, 682, 683, 684, 685, 686, 687, 173, 174, 175, - 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, - 186, 187, 188, 189, 190, 191, 192, 690, 691, 692, - 693, 694, 695, 696, 697, 698, 699, 700, 701, 702, - 703, 704, 705, 706, 707, 708, 709, 710, 117, 713, - 714, 338, 717, 718, 261, 262, 263, 264, 265, 266, - 267, 268, 269, 270, 725, 726, 727, 728, 729, 730, - 731, 732, 733, 734, 735, 282, 283, 284, 285, 286, - 287, 288, 289, 290, 291, 292, 359, 361, 738, 739, - 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, - 750, 751, 328, 329, 761, 762, 763, 10, 10, 10, + 274, 275, 276, 277, 278, 279, 280, 301, 309, 310, + 312, 313, 315, 316, 317, 318, 319, 322, 323, 324, + 325, 326, 327, 328, 329, 330, 331, 332, 333, 334, + 338, 347, 348, 349, 350, 354, 355, 356, 357, 358, + 359, 360, 361, 362, 363, 364, 365, 366, 367, 369, + 371, 372, 373, 374, 375, 376, 383, 408, 409, 410, + 411, 412, 413, 414, 415, 416, 417, 418, 419, 420, + 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, + 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, + 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, + 451, 452, 453, 454, 455, 456, 457, 458, 459, 460, + 461, 462, 463, 464, 465, 466, 467, 468, 469, 470, + 471, 472, 473, 474, 475, 476, 477, 478, 479, 480, + 481, 482, 483, 484, 485, 486, 487, 488, 489, 490, + 491, 492, 493, 494, 495, 496, 497, 498, 499, 500, + 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, + 511, 512, 513, 514, 515, 516, 517, 518, 519, 520, + 521, 522, 523, 524, 525, 526, 527, 528, 529, 530, + 531, 532, 533, 534, 535, 536, 537, 538, 539, 540, + 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, + 551, 552, 553, 554, 555, 556, 557, 558, 559, 560, + 561, 562, 563, 564, 565, 566, 567, 568, 569, 570, + 571, 572, 573, 574, 575, 576, 577, 578, 579, 580, + 581, 582, 583, 584, 585, 586, 587, 588, 589, 590, + 591, 592, 593, 594, 595, 596, 597, 598, 599, 600, + 601, 602, 603, 604, 605, 606, 607, 608, 609, 610, + 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, + 621, 622, 623, 624, 625, 626, 627, 628, 629, 630, + 631, 632, 633, 634, 635, 636, 637, 638, 639, 640, + 641, 642, 643, 644, 645, 646, 647, 648, 649, 650, + 651, 652, 653, 654, 729, 730, 731, 732, 770, 771, + 772, 773, 774, 775, 776, 47, 49, 50, 112, 145, + 148, 157, 321, 387, 655, 656, 657, 658, 659, 660, + 661, 662, 47, 55, 56, 144, 146, 149, 320, 391, + 663, 664, 665, 666, 667, 668, 669, 47, 83, 84, + 110, 194, 195, 240, 395, 680, 681, 682, 683, 684, + 685, 686, 47, 302, 304, 305, 306, 307, 308, 314, + 351, 352, 398, 670, 671, 672, 673, 674, 675, 676, + 677, 678, 679, 340, 341, 342, 343, 344, 353, 399, + 400, 401, 402, 403, 404, 407, 670, 671, 672, 673, + 674, 677, 99, 100, 101, 102, 103, 104, 105, 106, + 689, 690, 691, 692, 693, 694, 695, 696, 697, 173, + 174, 175, 176, 177, 178, 179, 180, 181, 182, 183, + 184, 185, 186, 187, 188, 189, 190, 191, 192, 700, + 701, 702, 703, 704, 705, 706, 707, 708, 709, 710, + 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, + 117, 723, 724, 346, 727, 728, 261, 262, 263, 264, + 265, 266, 267, 268, 269, 270, 735, 736, 737, 738, + 739, 740, 741, 742, 743, 744, 745, 282, 283, 284, + 285, 286, 287, 288, 289, 290, 291, 292, 293, 294, + 295, 296, 297, 298, 299, 300, 368, 370, 748, 749, + 750, 751, 752, 753, 754, 755, 756, 757, 758, 759, + 760, 761, 762, 763, 764, 765, 766, 767, 768, 769, + 336, 337, 779, 780, 781, 10, 10, 10, 10, 10, + 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, @@ -2387,89 +2435,91 @@ static const yytype_int16 yystos[] = 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, 10, - 10, 10, 10, 10, 10, 10, 10 + 10, 10, 10, 10 }; /* YYR1[YYN] -- Symbol number of symbol that rule YYN derives. */ static const yytype_int16 yyr1[] = { - 0, 368, 369, 369, 370, 370, 370, 370, 370, 370, - 370, 370, 370, 370, 370, 370, 370, 370, 371, 372, - 373, 373, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 374, - 374, 374, 374, 374, 374, 374, 374, 374, 374, 375, - 376, 377, 377, 378, 378, 378, 378, 378, 378, 378, - 378, 379, 380, 381, 381, 382, 382, 382, 382, 382, - 382, 382, 383, 384, 385, 385, 386, 386, 386, 386, - 386, 386, 386, 387, 388, 388, 389, 389, 389, 389, - 389, 389, 389, 389, 389, 389, 390, 391, 392, 393, - 394, 395, 396, 397, 397, 398, 398, 398, 398, 398, + 0, 377, 378, 378, 379, 379, 379, 379, 379, 379, + 379, 379, 379, 379, 379, 379, 379, 379, 380, 381, + 382, 382, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 383, 383, 383, 383, 383, 383, 383, 383, 383, 383, + 384, 385, 386, 386, 387, 387, 387, 387, 387, 387, + 387, 387, 388, 389, 390, 390, 391, 391, 391, 391, + 391, 391, 391, 392, 393, 394, 394, 395, 395, 395, + 395, 395, 395, 395, 396, 397, 397, 398, 398, 398, 398, 398, 398, 398, 398, 398, 398, 399, 400, 401, - 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, - 412, 413, 414, 415, 416, 417, 418, 419, 420, 421, - 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, - 432, 433, 434, 435, 436, 437, 438, 439, 440, 441, - 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, - 452, 453, 454, 455, 456, 457, 458, 459, 460, 461, - 462, 463, 464, 465, 466, 467, 468, 469, 470, 471, - 472, 473, 474, 475, 476, 477, 478, 479, 480, 481, - 482, 483, 484, 485, 486, 487, 488, 489, 490, 491, - 492, 493, 494, 495, 496, 497, 498, 499, 500, 501, - 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, - 512, 513, 514, 515, 516, 517, 518, 519, 520, 521, - 522, 523, 524, 525, 526, 527, 528, 529, 530, 531, - 532, 533, 534, 535, 536, 537, 538, 539, 540, 541, - 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, - 552, 553, 554, 555, 556, 557, 558, 559, 560, 561, - 562, 563, 564, 565, 566, 567, 568, 569, 570, 571, - 572, 573, 574, 575, 576, 577, 578, 579, 580, 581, - 582, 583, 584, 585, 586, 587, 588, 589, 590, 591, - 592, 593, 594, 595, 596, 597, 598, 599, 600, 601, - 602, 603, 604, 605, 606, 607, 608, 609, 610, 611, - 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, - 622, 623, 624, 625, 626, 627, 628, 629, 630, 631, - 632, 633, 634, 635, 636, 637, 638, 639, 640, 641, - 642, 643, 644, 645, 646, 647, 648, 649, 650, 651, - 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, - 662, 663, 664, 665, 666, 667, 668, 669, 670, 671, - 672, 673, 674, 675, 676, 677, 678, 678, 679, 679, - 679, 679, 679, 679, 679, 679, 680, 681, 682, 683, - 684, 685, 686, 687, 688, 689, 689, 690, 690, 690, - 690, 690, 690, 690, 690, 690, 690, 690, 690, 690, - 690, 690, 690, 690, 690, 690, 690, 691, 692, 693, - 694, 695, 696, 697, 698, 699, 700, 701, 702, 703, - 704, 705, 706, 707, 708, 709, 710, 711, 712, 712, - 713, 714, 715, 716, 716, 717, 718, 719, 720, 721, - 722, 723, 724, 724, 725, 725, 725, 725, 725, 725, - 725, 725, 725, 725, 726, 727, 728, 729, 730, 731, - 732, 733, 734, 735, 736, 737, 737, 738, 738, 738, - 738, 738, 738, 738, 738, 738, 738, 738, 738, 738, - 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, + 402, 403, 404, 405, 406, 406, 407, 407, 407, 407, + 407, 407, 407, 407, 407, 407, 407, 407, 408, 409, + 410, 411, 412, 413, 414, 415, 416, 417, 418, 419, + 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, + 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, + 440, 441, 442, 443, 444, 445, 446, 447, 448, 449, + 450, 451, 452, 453, 454, 455, 456, 457, 458, 459, + 460, 461, 462, 463, 464, 465, 466, 467, 468, 469, + 470, 471, 472, 473, 474, 475, 476, 477, 478, 479, + 480, 481, 482, 483, 484, 485, 486, 487, 488, 489, + 490, 491, 492, 493, 494, 495, 496, 497, 498, 499, + 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, + 510, 511, 512, 513, 514, 515, 516, 517, 518, 519, + 520, 521, 522, 523, 524, 525, 526, 527, 528, 529, + 530, 531, 532, 533, 534, 535, 536, 537, 538, 539, + 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, + 550, 551, 552, 553, 554, 555, 556, 557, 558, 559, + 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, + 570, 571, 572, 573, 574, 575, 576, 577, 578, 579, + 580, 581, 582, 583, 584, 585, 586, 587, 588, 589, + 590, 591, 592, 593, 594, 595, 596, 597, 598, 599, + 600, 601, 602, 603, 604, 605, 606, 607, 608, 609, + 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, + 620, 621, 622, 623, 624, 625, 626, 627, 628, 629, + 630, 631, 632, 633, 634, 635, 636, 637, 638, 639, + 640, 641, 642, 643, 644, 645, 646, 647, 648, 649, + 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, + 660, 661, 662, 663, 664, 665, 666, 667, 668, 669, + 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, + 680, 681, 682, 683, 684, 685, 686, 687, 688, 688, + 689, 689, 689, 689, 689, 689, 689, 689, 690, 691, + 692, 693, 694, 695, 696, 697, 698, 699, 699, 700, + 700, 700, 700, 700, 700, 700, 700, 700, 700, 700, + 700, 700, 700, 700, 700, 700, 700, 700, 700, 701, + 702, 703, 704, 705, 706, 707, 708, 709, 710, 711, + 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, + 722, 722, 723, 724, 725, 726, 726, 727, 728, 729, + 730, 731, 732, 733, 734, 734, 735, 735, 735, 735, + 735, 735, 735, 735, 735, 735, 736, 737, 738, 739, + 740, 741, 742, 743, 744, 745, 746, 747, 747, 748, + 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, + 748, 748, 748, 748, 748, 748, 748, 748, 748, 748, 749, 750, 751, 752, 753, 754, 755, 756, 757, 758, - 759, 760, 760, 761, 761, 762, 763 + 759, 760, 761, 762, 763, 764, 765, 766, 767, 768, + 769, 770, 771, 772, 773, 774, 775, 776, 777, 778, + 778, 779, 779, 780, 781 }; /* YYR2[YYN] -- Number of symbols on the right hand side of rule YYN. */ @@ -2502,14 +2552,14 @@ static const yytype_int8 yyr2[] = 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, - 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, - 1, 2, 1, 2, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, + 2, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 2, 1, 2, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 0, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, - 2, 2, 1, 2, 0, 1, 1, 1, 1, 1, + 1, 1, 1, 2, 1, 2, 0, 1, 1, 1, + 1, 1, 1, 1, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, + 2, 2, 2, 1, 2, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, @@ -2524,34 +2574,36 @@ static const yytype_int8 yyr2[] = 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 3, 2, 2, 2, 2, 2, 2, 2, 2, 3, - 3, 2, 2, 2, 2, 2, 2, 3, 3, 4, - 4, 4, 3, 3, 4, 4, 3, 3, 2, 2, - 2, 2, 2, 2, 2, 3, 3, 2, 2, 2, + 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 3, 2, 2, 2, 2, 2, 2, 3, 3, + 4, 4, 4, 3, 3, 4, 4, 3, 3, 2, + 2, 2, 2, 2, 2, 2, 3, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 3, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, - 3, 3, 2, 2, 2, 1, 2, 0, 1, 1, - 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, - 2, 2, 2, 2, 1, 2, 0, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 3, 3, 2, 2, 2, 1, 2, 0, + 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 2, 2, 2, 1, 2, 0, - 1, 2, 1, 2, 0, 1, 2, 2, 2, 3, - 3, 1, 2, 0, 1, 1, 1, 1, 1, 1, - 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 2, 1, 2, 0, 1, 1, 1, + 2, 2, 2, 2, 2, 2, 2, 2, 2, 1, + 2, 0, 1, 2, 1, 2, 0, 1, 2, 2, + 2, 3, 3, 1, 2, 0, 1, 1, 1, 1, + 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, + 2, 2, 2, 2, 2, 2, 1, 2, 0, 1, + 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, - 2, 2, 2, 3, 2, 2, 2, 2, 2, 2, - 1, 2, 0, 1, 1, 2, 2 + 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, + 2, 3, 2, 2, 2, 2, 2, 2, 1, 2, + 0, 1, 1, 2, 2 }; @@ -3019,36 +3071,36 @@ yyreduce: switch (yyn) { case 18: /* force_toplevel: VAR_FORCE_TOPLEVEL */ -#line 224 "util/configparser.y" +#line 230 "util/configparser.y" { OUTYY(("\nP(force-toplevel)\n")); cfg_parser->started_toplevel = 0; } -#line 3028 "util/configparser.c" +#line 3080 "util/configparser.c" break; case 19: /* serverstart: VAR_SERVER */ -#line 231 "util/configparser.y" +#line 237 "util/configparser.y" { OUTYY(("\nP(server:)\n")); cfg_parser->started_toplevel = 1; } -#line 3037 "util/configparser.c" +#line 3089 "util/configparser.c" break; - case 279: /* stub_clause: stubstart contents_stub */ -#line 355 "util/configparser.y" + case 280: /* stub_clause: stubstart contents_stub */ +#line 362 "util/configparser.y" { /* stub end */ if(cfg_parser->cfg->stubs && !cfg_parser->cfg->stubs->name) yyerror("stub-zone without name"); } -#line 3048 "util/configparser.c" +#line 3100 "util/configparser.c" break; - case 280: /* stubstart: VAR_STUB_ZONE */ -#line 363 "util/configparser.y" + case 281: /* stubstart: VAR_STUB_ZONE */ +#line 370 "util/configparser.y" { struct config_stub* s; OUTYY(("\nP(stub_zone:)\n")); @@ -3061,22 +3113,22 @@ yyreduce: yyerror("out of memory"); } } -#line 3065 "util/configparser.c" +#line 3117 "util/configparser.c" break; - case 291: /* forward_clause: forwardstart contents_forward */ -#line 382 "util/configparser.y" + case 292: /* forward_clause: forwardstart contents_forward */ +#line 389 "util/configparser.y" { /* forward end */ if(cfg_parser->cfg->forwards && !cfg_parser->cfg->forwards->name) yyerror("forward-zone without name"); } -#line 3076 "util/configparser.c" +#line 3128 "util/configparser.c" break; - case 292: /* forwardstart: VAR_FORWARD_ZONE */ -#line 390 "util/configparser.y" + case 293: /* forwardstart: VAR_FORWARD_ZONE */ +#line 397 "util/configparser.y" { struct config_stub* s; OUTYY(("\nP(forward_zone:)\n")); @@ -3089,22 +3141,22 @@ yyreduce: yyerror("out of memory"); } } -#line 3093 "util/configparser.c" +#line 3145 "util/configparser.c" break; - case 302: /* view_clause: viewstart contents_view */ -#line 409 "util/configparser.y" + case 303: /* view_clause: viewstart contents_view */ +#line 416 "util/configparser.y" { /* view end */ if(cfg_parser->cfg->views && !cfg_parser->cfg->views->name) yyerror("view without name"); } -#line 3104 "util/configparser.c" +#line 3156 "util/configparser.c" break; - case 303: /* viewstart: VAR_VIEW */ -#line 417 "util/configparser.y" + case 304: /* viewstart: VAR_VIEW */ +#line 424 "util/configparser.y" { struct config_view* s; OUTYY(("\nP(view:)\n")); @@ -3117,11 +3169,11 @@ yyreduce: yyerror("out of memory"); } } -#line 3121 "util/configparser.c" +#line 3173 "util/configparser.c" break; - case 313: /* authstart: VAR_AUTH_ZONE */ -#line 436 "util/configparser.y" + case 314: /* authstart: VAR_AUTH_ZONE */ +#line 443 "util/configparser.y" { struct config_auth* s; OUTYY(("\nP(auth_zone:)\n")); @@ -3141,11 +3193,11 @@ yyreduce: yyerror("out of memory"); } } -#line 3145 "util/configparser.c" +#line 3197 "util/configparser.c" break; - case 326: /* rpz_tag: VAR_TAGS STRING_ARG */ -#line 464 "util/configparser.y" + case 327: /* rpz_tag: VAR_TAGS STRING_ARG */ +#line 471 "util/configparser.y" { uint8_t* bitlist; size_t len = 0; @@ -3162,11 +3214,11 @@ yyreduce: } } -#line 3166 "util/configparser.c" +#line 3218 "util/configparser.c" break; - case 327: /* rpz_action_override: VAR_RPZ_ACTION_OVERRIDE STRING_ARG */ -#line 483 "util/configparser.y" + case 328: /* rpz_action_override: VAR_RPZ_ACTION_OVERRIDE STRING_ARG */ +#line 490 "util/configparser.y" { OUTYY(("P(rpz_action_override:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "nxdomain")!=0 && strcmp((yyvsp[0].str), "nodata")!=0 && @@ -3181,21 +3233,21 @@ yyreduce: cfg_parser->cfg->auths->rpz_action_override = (yyvsp[0].str); } } -#line 3185 "util/configparser.c" +#line 3237 "util/configparser.c" break; - case 328: /* rpz_cname_override: VAR_RPZ_CNAME_OVERRIDE STRING_ARG */ -#line 500 "util/configparser.y" + case 329: /* rpz_cname_override: VAR_RPZ_CNAME_OVERRIDE STRING_ARG */ +#line 507 "util/configparser.y" { OUTYY(("P(rpz_cname_override:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->auths->rpz_cname); cfg_parser->cfg->auths->rpz_cname = (yyvsp[0].str); } -#line 3195 "util/configparser.c" +#line 3247 "util/configparser.c" break; - case 329: /* rpz_log: VAR_RPZ_LOG STRING_ARG */ -#line 508 "util/configparser.y" + case 330: /* rpz_log: VAR_RPZ_LOG STRING_ARG */ +#line 515 "util/configparser.y" { OUTYY(("P(rpz_log:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3203,21 +3255,21 @@ yyreduce: else cfg_parser->cfg->auths->rpz_log = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3207 "util/configparser.c" +#line 3259 "util/configparser.c" break; - case 330: /* rpz_log_name: VAR_RPZ_LOG_NAME STRING_ARG */ -#line 518 "util/configparser.y" + case 331: /* rpz_log_name: VAR_RPZ_LOG_NAME STRING_ARG */ +#line 525 "util/configparser.y" { OUTYY(("P(rpz_log_name:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->auths->rpz_log_name); cfg_parser->cfg->auths->rpz_log_name = (yyvsp[0].str); } -#line 3217 "util/configparser.c" +#line 3269 "util/configparser.c" break; - case 331: /* rpz_signal_nxdomain_ra: VAR_RPZ_SIGNAL_NXDOMAIN_RA STRING_ARG */ -#line 525 "util/configparser.y" + case 332: /* rpz_signal_nxdomain_ra: VAR_RPZ_SIGNAL_NXDOMAIN_RA STRING_ARG */ +#line 532 "util/configparser.y" { OUTYY(("P(rpz_signal_nxdomain_ra:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3225,11 +3277,11 @@ yyreduce: else cfg_parser->cfg->auths->rpz_signal_nxdomain_ra = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3229 "util/configparser.c" +#line 3281 "util/configparser.c" break; - case 332: /* rpzstart: VAR_RPZ */ -#line 535 "util/configparser.y" + case 333: /* rpzstart: VAR_RPZ */ +#line 542 "util/configparser.y" { struct config_auth* s; OUTYY(("\nP(rpz:)\n")); @@ -3247,11 +3299,11 @@ yyreduce: yyerror("out of memory"); } } -#line 3251 "util/configparser.c" +#line 3303 "util/configparser.c" break; - case 347: /* server_num_threads: VAR_NUM_THREADS STRING_ARG */ -#line 560 "util/configparser.y" + case 348: /* server_num_threads: VAR_NUM_THREADS STRING_ARG */ +#line 567 "util/configparser.y" { OUTYY(("P(server_num_threads:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3259,11 +3311,11 @@ yyreduce: else cfg_parser->cfg->num_threads = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3263 "util/configparser.c" +#line 3315 "util/configparser.c" break; - case 348: /* server_verbosity: VAR_VERBOSITY STRING_ARG */ -#line 569 "util/configparser.y" + case 349: /* server_verbosity: VAR_VERBOSITY STRING_ARG */ +#line 576 "util/configparser.y" { OUTYY(("P(server_verbosity:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3271,11 +3323,11 @@ yyreduce: else cfg_parser->cfg->verbosity = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3275 "util/configparser.c" +#line 3327 "util/configparser.c" break; - case 349: /* server_statistics_interval: VAR_STATISTICS_INTERVAL STRING_ARG */ -#line 578 "util/configparser.y" + case 350: /* server_statistics_interval: VAR_STATISTICS_INTERVAL STRING_ARG */ +#line 585 "util/configparser.y" { OUTYY(("P(server_statistics_interval:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "") == 0 || strcmp((yyvsp[0].str), "0") == 0) @@ -3285,11 +3337,11 @@ yyreduce: else cfg_parser->cfg->stat_interval = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3289 "util/configparser.c" +#line 3341 "util/configparser.c" break; - case 350: /* server_statistics_cumulative: VAR_STATISTICS_CUMULATIVE STRING_ARG */ -#line 589 "util/configparser.y" + case 351: /* server_statistics_cumulative: VAR_STATISTICS_CUMULATIVE STRING_ARG */ +#line 596 "util/configparser.y" { OUTYY(("P(server_statistics_cumulative:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3297,11 +3349,11 @@ yyreduce: else cfg_parser->cfg->stat_cumulative = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3301 "util/configparser.c" +#line 3353 "util/configparser.c" break; - case 351: /* server_extended_statistics: VAR_EXTENDED_STATISTICS STRING_ARG */ -#line 598 "util/configparser.y" + case 352: /* server_extended_statistics: VAR_EXTENDED_STATISTICS STRING_ARG */ +#line 605 "util/configparser.y" { OUTYY(("P(server_extended_statistics:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3309,11 +3361,11 @@ yyreduce: else cfg_parser->cfg->stat_extended = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3313 "util/configparser.c" +#line 3365 "util/configparser.c" break; - case 352: /* server_statistics_inhibit_zero: VAR_STATISTICS_INHIBIT_ZERO STRING_ARG */ -#line 607 "util/configparser.y" + case 353: /* server_statistics_inhibit_zero: VAR_STATISTICS_INHIBIT_ZERO STRING_ARG */ +#line 614 "util/configparser.y" { OUTYY(("P(server_statistics_inhibit_zero:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3321,11 +3373,11 @@ yyreduce: else cfg_parser->cfg->stat_inhibit_zero = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3325 "util/configparser.c" +#line 3377 "util/configparser.c" break; - case 353: /* server_shm_enable: VAR_SHM_ENABLE STRING_ARG */ -#line 616 "util/configparser.y" + case 354: /* server_shm_enable: VAR_SHM_ENABLE STRING_ARG */ +#line 623 "util/configparser.y" { OUTYY(("P(server_shm_enable:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3333,11 +3385,11 @@ yyreduce: else cfg_parser->cfg->shm_enable = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3337 "util/configparser.c" +#line 3389 "util/configparser.c" break; - case 354: /* server_shm_key: VAR_SHM_KEY STRING_ARG */ -#line 625 "util/configparser.y" + case 355: /* server_shm_key: VAR_SHM_KEY STRING_ARG */ +#line 632 "util/configparser.y" { OUTYY(("P(server_shm_key:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "") == 0 || strcmp((yyvsp[0].str), "0") == 0) @@ -3347,11 +3399,11 @@ yyreduce: else cfg_parser->cfg->shm_key = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3351 "util/configparser.c" +#line 3403 "util/configparser.c" break; - case 355: /* server_port: VAR_PORT STRING_ARG */ -#line 636 "util/configparser.y" + case 356: /* server_port: VAR_PORT STRING_ARG */ +#line 643 "util/configparser.y" { OUTYY(("P(server_port:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -3359,11 +3411,11 @@ yyreduce: else cfg_parser->cfg->port = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3363 "util/configparser.c" +#line 3415 "util/configparser.c" break; - case 356: /* server_send_client_subnet: VAR_SEND_CLIENT_SUBNET STRING_ARG */ -#line 645 "util/configparser.y" + case 357: /* server_send_client_subnet: VAR_SEND_CLIENT_SUBNET STRING_ARG */ +#line 652 "util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(server_send_client_subnet:%s)\n", (yyvsp[0].str))); @@ -3374,11 +3426,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 3378 "util/configparser.c" +#line 3430 "util/configparser.c" break; - case 357: /* server_client_subnet_zone: VAR_CLIENT_SUBNET_ZONE STRING_ARG */ -#line 657 "util/configparser.y" + case 358: /* server_client_subnet_zone: VAR_CLIENT_SUBNET_ZONE STRING_ARG */ +#line 664 "util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(server_client_subnet_zone:%s)\n", (yyvsp[0].str))); @@ -3390,11 +3442,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 3394 "util/configparser.c" +#line 3446 "util/configparser.c" break; - case 358: /* server_client_subnet_always_forward: VAR_CLIENT_SUBNET_ALWAYS_FORWARD STRING_ARG */ -#line 671 "util/configparser.y" + case 359: /* server_client_subnet_always_forward: VAR_CLIENT_SUBNET_ALWAYS_FORWARD STRING_ARG */ +#line 678 "util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(server_client_subnet_always_forward:%s)\n", (yyvsp[0].str))); @@ -3408,11 +3460,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 3412 "util/configparser.c" +#line 3464 "util/configparser.c" break; - case 359: /* server_client_subnet_opcode: VAR_CLIENT_SUBNET_OPCODE STRING_ARG */ -#line 686 "util/configparser.y" + case 360: /* server_client_subnet_opcode: VAR_CLIENT_SUBNET_OPCODE STRING_ARG */ +#line 693 "util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(client_subnet_opcode:%s)\n", (yyvsp[0].str))); @@ -3422,11 +3474,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 3426 "util/configparser.c" +#line 3478 "util/configparser.c" break; - case 360: /* server_max_client_subnet_ipv4: VAR_MAX_CLIENT_SUBNET_IPV4 STRING_ARG */ -#line 697 "util/configparser.y" + case 361: /* server_max_client_subnet_ipv4: VAR_MAX_CLIENT_SUBNET_IPV4 STRING_ARG */ +#line 704 "util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(max_client_subnet_ipv4:%s)\n", (yyvsp[0].str))); @@ -3442,11 +3494,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 3446 "util/configparser.c" +#line 3498 "util/configparser.c" break; - case 361: /* server_max_client_subnet_ipv6: VAR_MAX_CLIENT_SUBNET_IPV6 STRING_ARG */ -#line 714 "util/configparser.y" + case 362: /* server_max_client_subnet_ipv6: VAR_MAX_CLIENT_SUBNET_IPV6 STRING_ARG */ +#line 721 "util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(max_client_subnet_ipv6:%s)\n", (yyvsp[0].str))); @@ -3462,11 +3514,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 3466 "util/configparser.c" +#line 3518 "util/configparser.c" break; - case 362: /* server_min_client_subnet_ipv4: VAR_MIN_CLIENT_SUBNET_IPV4 STRING_ARG */ -#line 731 "util/configparser.y" + case 363: /* server_min_client_subnet_ipv4: VAR_MIN_CLIENT_SUBNET_IPV4 STRING_ARG */ +#line 738 "util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(min_client_subnet_ipv4:%s)\n", (yyvsp[0].str))); @@ -3482,11 +3534,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 3486 "util/configparser.c" +#line 3538 "util/configparser.c" break; - case 363: /* server_min_client_subnet_ipv6: VAR_MIN_CLIENT_SUBNET_IPV6 STRING_ARG */ -#line 748 "util/configparser.y" + case 364: /* server_min_client_subnet_ipv6: VAR_MIN_CLIENT_SUBNET_IPV6 STRING_ARG */ +#line 755 "util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(min_client_subnet_ipv6:%s)\n", (yyvsp[0].str))); @@ -3502,11 +3554,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 3506 "util/configparser.c" +#line 3558 "util/configparser.c" break; - case 364: /* server_max_ecs_tree_size_ipv4: VAR_MAX_ECS_TREE_SIZE_IPV4 STRING_ARG */ -#line 765 "util/configparser.y" + case 365: /* server_max_ecs_tree_size_ipv4: VAR_MAX_ECS_TREE_SIZE_IPV4 STRING_ARG */ +#line 772 "util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(max_ecs_tree_size_ipv4:%s)\n", (yyvsp[0].str))); @@ -3520,11 +3572,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 3524 "util/configparser.c" +#line 3576 "util/configparser.c" break; - case 365: /* server_max_ecs_tree_size_ipv6: VAR_MAX_ECS_TREE_SIZE_IPV6 STRING_ARG */ -#line 780 "util/configparser.y" + case 366: /* server_max_ecs_tree_size_ipv6: VAR_MAX_ECS_TREE_SIZE_IPV6 STRING_ARG */ +#line 787 "util/configparser.y" { #ifdef CLIENT_SUBNET OUTYY(("P(max_ecs_tree_size_ipv6:%s)\n", (yyvsp[0].str))); @@ -3538,11 +3590,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 3542 "util/configparser.c" +#line 3594 "util/configparser.c" break; - case 366: /* server_interface: VAR_INTERFACE STRING_ARG */ -#line 795 "util/configparser.y" + case 367: /* server_interface: VAR_INTERFACE STRING_ARG */ +#line 802 "util/configparser.y" { OUTYY(("P(server_interface:%s)\n", (yyvsp[0].str))); if(cfg_parser->cfg->num_ifs == 0) @@ -3554,11 +3606,11 @@ yyreduce: else cfg_parser->cfg->ifs[cfg_parser->cfg->num_ifs++] = (yyvsp[0].str); } -#line 3558 "util/configparser.c" +#line 3610 "util/configparser.c" break; - case 367: /* server_outgoing_interface: VAR_OUTGOING_INTERFACE STRING_ARG */ -#line 808 "util/configparser.y" + case 368: /* server_outgoing_interface: VAR_OUTGOING_INTERFACE STRING_ARG */ +#line 815 "util/configparser.y" { OUTYY(("P(server_outgoing_interface:%s)\n", (yyvsp[0].str))); if(cfg_parser->cfg->num_out_ifs == 0) @@ -3572,11 +3624,11 @@ yyreduce: cfg_parser->cfg->out_ifs[ cfg_parser->cfg->num_out_ifs++] = (yyvsp[0].str); } -#line 3576 "util/configparser.c" +#line 3628 "util/configparser.c" break; - case 368: /* server_outgoing_range: VAR_OUTGOING_RANGE STRING_ARG */ -#line 823 "util/configparser.y" + case 369: /* server_outgoing_range: VAR_OUTGOING_RANGE STRING_ARG */ +#line 830 "util/configparser.y" { OUTYY(("P(server_outgoing_range:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -3584,11 +3636,11 @@ yyreduce: else cfg_parser->cfg->outgoing_num_ports = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3588 "util/configparser.c" +#line 3640 "util/configparser.c" break; - case 369: /* server_outgoing_port_permit: VAR_OUTGOING_PORT_PERMIT STRING_ARG */ -#line 832 "util/configparser.y" + case 370: /* server_outgoing_port_permit: VAR_OUTGOING_PORT_PERMIT STRING_ARG */ +#line 839 "util/configparser.y" { OUTYY(("P(server_outgoing_port_permit:%s)\n", (yyvsp[0].str))); if(!cfg_mark_ports((yyvsp[0].str), 1, @@ -3596,11 +3648,11 @@ yyreduce: yyerror("port number or range (\"low-high\") expected"); free((yyvsp[0].str)); } -#line 3600 "util/configparser.c" +#line 3652 "util/configparser.c" break; - case 370: /* server_outgoing_port_avoid: VAR_OUTGOING_PORT_AVOID STRING_ARG */ -#line 841 "util/configparser.y" + case 371: /* server_outgoing_port_avoid: VAR_OUTGOING_PORT_AVOID STRING_ARG */ +#line 848 "util/configparser.y" { OUTYY(("P(server_outgoing_port_avoid:%s)\n", (yyvsp[0].str))); if(!cfg_mark_ports((yyvsp[0].str), 0, @@ -3608,11 +3660,11 @@ yyreduce: yyerror("port number or range (\"low-high\") expected"); free((yyvsp[0].str)); } -#line 3612 "util/configparser.c" +#line 3664 "util/configparser.c" break; - case 371: /* server_outgoing_num_tcp: VAR_OUTGOING_NUM_TCP STRING_ARG */ -#line 850 "util/configparser.y" + case 372: /* server_outgoing_num_tcp: VAR_OUTGOING_NUM_TCP STRING_ARG */ +#line 857 "util/configparser.y" { OUTYY(("P(server_outgoing_num_tcp:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3620,11 +3672,11 @@ yyreduce: else cfg_parser->cfg->outgoing_num_tcp = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3624 "util/configparser.c" +#line 3676 "util/configparser.c" break; - case 372: /* server_incoming_num_tcp: VAR_INCOMING_NUM_TCP STRING_ARG */ -#line 859 "util/configparser.y" + case 373: /* server_incoming_num_tcp: VAR_INCOMING_NUM_TCP STRING_ARG */ +#line 866 "util/configparser.y" { OUTYY(("P(server_incoming_num_tcp:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3632,11 +3684,11 @@ yyreduce: else cfg_parser->cfg->incoming_num_tcp = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3636 "util/configparser.c" +#line 3688 "util/configparser.c" break; - case 373: /* server_interface_automatic: VAR_INTERFACE_AUTOMATIC STRING_ARG */ -#line 868 "util/configparser.y" + case 374: /* server_interface_automatic: VAR_INTERFACE_AUTOMATIC STRING_ARG */ +#line 875 "util/configparser.y" { OUTYY(("P(server_interface_automatic:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3644,21 +3696,21 @@ yyreduce: else cfg_parser->cfg->if_automatic = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3648 "util/configparser.c" +#line 3700 "util/configparser.c" break; - case 374: /* server_interface_automatic_ports: VAR_INTERFACE_AUTOMATIC_PORTS STRING_ARG */ -#line 877 "util/configparser.y" + case 375: /* server_interface_automatic_ports: VAR_INTERFACE_AUTOMATIC_PORTS STRING_ARG */ +#line 884 "util/configparser.y" { OUTYY(("P(server_interface_automatic_ports:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->if_automatic_ports); cfg_parser->cfg->if_automatic_ports = (yyvsp[0].str); } -#line 3658 "util/configparser.c" +#line 3710 "util/configparser.c" break; - case 375: /* server_do_ip4: VAR_DO_IP4 STRING_ARG */ -#line 884 "util/configparser.y" + case 376: /* server_do_ip4: VAR_DO_IP4 STRING_ARG */ +#line 891 "util/configparser.y" { OUTYY(("P(server_do_ip4:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3666,11 +3718,11 @@ yyreduce: else cfg_parser->cfg->do_ip4 = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3670 "util/configparser.c" +#line 3722 "util/configparser.c" break; - case 376: /* server_do_ip6: VAR_DO_IP6 STRING_ARG */ -#line 893 "util/configparser.y" + case 377: /* server_do_ip6: VAR_DO_IP6 STRING_ARG */ +#line 900 "util/configparser.y" { OUTYY(("P(server_do_ip6:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3678,11 +3730,11 @@ yyreduce: else cfg_parser->cfg->do_ip6 = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3682 "util/configparser.c" +#line 3734 "util/configparser.c" break; - case 377: /* server_do_nat64: VAR_DO_NAT64 STRING_ARG */ -#line 902 "util/configparser.y" + case 378: /* server_do_nat64: VAR_DO_NAT64 STRING_ARG */ +#line 909 "util/configparser.y" { OUTYY(("P(server_do_nat64:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3690,11 +3742,11 @@ yyreduce: else cfg_parser->cfg->do_nat64 = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3694 "util/configparser.c" +#line 3746 "util/configparser.c" break; - case 378: /* server_do_udp: VAR_DO_UDP STRING_ARG */ -#line 911 "util/configparser.y" + case 379: /* server_do_udp: VAR_DO_UDP STRING_ARG */ +#line 918 "util/configparser.y" { OUTYY(("P(server_do_udp:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3702,11 +3754,11 @@ yyreduce: else cfg_parser->cfg->do_udp = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3706 "util/configparser.c" +#line 3758 "util/configparser.c" break; - case 379: /* server_do_tcp: VAR_DO_TCP STRING_ARG */ -#line 920 "util/configparser.y" + case 380: /* server_do_tcp: VAR_DO_TCP STRING_ARG */ +#line 927 "util/configparser.y" { OUTYY(("P(server_do_tcp:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3714,11 +3766,11 @@ yyreduce: else cfg_parser->cfg->do_tcp = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3718 "util/configparser.c" +#line 3770 "util/configparser.c" break; - case 380: /* server_prefer_ip4: VAR_PREFER_IP4 STRING_ARG */ -#line 929 "util/configparser.y" + case 381: /* server_prefer_ip4: VAR_PREFER_IP4 STRING_ARG */ +#line 936 "util/configparser.y" { OUTYY(("P(server_prefer_ip4:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3726,11 +3778,11 @@ yyreduce: else cfg_parser->cfg->prefer_ip4 = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3730 "util/configparser.c" +#line 3782 "util/configparser.c" break; - case 381: /* server_prefer_ip6: VAR_PREFER_IP6 STRING_ARG */ -#line 938 "util/configparser.y" + case 382: /* server_prefer_ip6: VAR_PREFER_IP6 STRING_ARG */ +#line 945 "util/configparser.y" { OUTYY(("P(server_prefer_ip6:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3738,11 +3790,11 @@ yyreduce: else cfg_parser->cfg->prefer_ip6 = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3742 "util/configparser.c" +#line 3794 "util/configparser.c" break; - case 382: /* server_tcp_mss: VAR_TCP_MSS STRING_ARG */ -#line 947 "util/configparser.y" + case 383: /* server_tcp_mss: VAR_TCP_MSS STRING_ARG */ +#line 954 "util/configparser.y" { OUTYY(("P(server_tcp_mss:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3750,11 +3802,11 @@ yyreduce: else cfg_parser->cfg->tcp_mss = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3754 "util/configparser.c" +#line 3806 "util/configparser.c" break; - case 383: /* server_outgoing_tcp_mss: VAR_OUTGOING_TCP_MSS STRING_ARG */ -#line 956 "util/configparser.y" + case 384: /* server_outgoing_tcp_mss: VAR_OUTGOING_TCP_MSS STRING_ARG */ +#line 963 "util/configparser.y" { OUTYY(("P(server_outgoing_tcp_mss:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3762,11 +3814,11 @@ yyreduce: else cfg_parser->cfg->outgoing_tcp_mss = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3766 "util/configparser.c" +#line 3818 "util/configparser.c" break; - case 384: /* server_tcp_idle_timeout: VAR_TCP_IDLE_TIMEOUT STRING_ARG */ -#line 965 "util/configparser.y" + case 385: /* server_tcp_idle_timeout: VAR_TCP_IDLE_TIMEOUT STRING_ARG */ +#line 972 "util/configparser.y" { OUTYY(("P(server_tcp_idle_timeout:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3778,11 +3830,11 @@ yyreduce: else cfg_parser->cfg->tcp_idle_timeout = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3782 "util/configparser.c" +#line 3834 "util/configparser.c" break; - case 385: /* server_max_reuse_tcp_queries: VAR_MAX_REUSE_TCP_QUERIES STRING_ARG */ -#line 978 "util/configparser.y" + case 386: /* server_max_reuse_tcp_queries: VAR_MAX_REUSE_TCP_QUERIES STRING_ARG */ +#line 985 "util/configparser.y" { OUTYY(("P(server_max_reuse_tcp_queries:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3792,11 +3844,11 @@ yyreduce: else cfg_parser->cfg->max_reuse_tcp_queries = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3796 "util/configparser.c" +#line 3848 "util/configparser.c" break; - case 386: /* server_tcp_reuse_timeout: VAR_TCP_REUSE_TIMEOUT STRING_ARG */ -#line 989 "util/configparser.y" + case 387: /* server_tcp_reuse_timeout: VAR_TCP_REUSE_TIMEOUT STRING_ARG */ +#line 996 "util/configparser.y" { OUTYY(("P(server_tcp_reuse_timeout:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3806,11 +3858,11 @@ yyreduce: else cfg_parser->cfg->tcp_reuse_timeout = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3810 "util/configparser.c" +#line 3862 "util/configparser.c" break; - case 387: /* server_tcp_auth_query_timeout: VAR_TCP_AUTH_QUERY_TIMEOUT STRING_ARG */ -#line 1000 "util/configparser.y" + case 388: /* server_tcp_auth_query_timeout: VAR_TCP_AUTH_QUERY_TIMEOUT STRING_ARG */ +#line 1007 "util/configparser.y" { OUTYY(("P(server_tcp_auth_query_timeout:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3820,11 +3872,11 @@ yyreduce: else cfg_parser->cfg->tcp_auth_query_timeout = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3824 "util/configparser.c" +#line 3876 "util/configparser.c" break; - case 388: /* server_tcp_keepalive: VAR_EDNS_TCP_KEEPALIVE STRING_ARG */ -#line 1011 "util/configparser.y" + case 389: /* server_tcp_keepalive: VAR_EDNS_TCP_KEEPALIVE STRING_ARG */ +#line 1018 "util/configparser.y" { OUTYY(("P(server_tcp_keepalive:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3832,11 +3884,11 @@ yyreduce: else cfg_parser->cfg->do_tcp_keepalive = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3836 "util/configparser.c" +#line 3888 "util/configparser.c" break; - case 389: /* server_tcp_keepalive_timeout: VAR_EDNS_TCP_KEEPALIVE_TIMEOUT STRING_ARG */ -#line 1020 "util/configparser.y" + case 390: /* server_tcp_keepalive_timeout: VAR_EDNS_TCP_KEEPALIVE_TIMEOUT STRING_ARG */ +#line 1027 "util/configparser.y" { OUTYY(("P(server_tcp_keepalive_timeout:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3848,11 +3900,11 @@ yyreduce: else cfg_parser->cfg->tcp_keepalive_timeout = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3852 "util/configparser.c" +#line 3904 "util/configparser.c" break; - case 390: /* server_sock_queue_timeout: VAR_SOCK_QUEUE_TIMEOUT STRING_ARG */ -#line 1033 "util/configparser.y" + case 391: /* server_sock_queue_timeout: VAR_SOCK_QUEUE_TIMEOUT STRING_ARG */ +#line 1040 "util/configparser.y" { OUTYY(("P(server_sock_queue_timeout:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -3864,11 +3916,11 @@ yyreduce: else cfg_parser->cfg->sock_queue_timeout = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3868 "util/configparser.c" +#line 3920 "util/configparser.c" break; - case 391: /* server_tcp_upstream: VAR_TCP_UPSTREAM STRING_ARG */ -#line 1046 "util/configparser.y" + case 392: /* server_tcp_upstream: VAR_TCP_UPSTREAM STRING_ARG */ +#line 1053 "util/configparser.y" { OUTYY(("P(server_tcp_upstream:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3876,11 +3928,11 @@ yyreduce: else cfg_parser->cfg->tcp_upstream = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3880 "util/configparser.c" +#line 3932 "util/configparser.c" break; - case 392: /* server_udp_upstream_without_downstream: VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM STRING_ARG */ -#line 1055 "util/configparser.y" + case 393: /* server_udp_upstream_without_downstream: VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM STRING_ARG */ +#line 1062 "util/configparser.y" { OUTYY(("P(server_udp_upstream_without_downstream:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3888,11 +3940,11 @@ yyreduce: else cfg_parser->cfg->udp_upstream_without_downstream = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3892 "util/configparser.c" +#line 3944 "util/configparser.c" break; - case 393: /* server_ssl_upstream: VAR_SSL_UPSTREAM STRING_ARG */ -#line 1064 "util/configparser.y" + case 394: /* server_ssl_upstream: VAR_SSL_UPSTREAM STRING_ARG */ +#line 1071 "util/configparser.y" { OUTYY(("P(server_ssl_upstream:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3900,31 +3952,31 @@ yyreduce: else cfg_parser->cfg->ssl_upstream = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3904 "util/configparser.c" +#line 3956 "util/configparser.c" break; - case 394: /* server_ssl_service_key: VAR_SSL_SERVICE_KEY STRING_ARG */ -#line 1073 "util/configparser.y" + case 395: /* server_ssl_service_key: VAR_SSL_SERVICE_KEY STRING_ARG */ +#line 1080 "util/configparser.y" { OUTYY(("P(server_ssl_service_key:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->ssl_service_key); cfg_parser->cfg->ssl_service_key = (yyvsp[0].str); } -#line 3914 "util/configparser.c" +#line 3966 "util/configparser.c" break; - case 395: /* server_ssl_service_pem: VAR_SSL_SERVICE_PEM STRING_ARG */ -#line 1080 "util/configparser.y" + case 396: /* server_ssl_service_pem: VAR_SSL_SERVICE_PEM STRING_ARG */ +#line 1087 "util/configparser.y" { OUTYY(("P(server_ssl_service_pem:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->ssl_service_pem); cfg_parser->cfg->ssl_service_pem = (yyvsp[0].str); } -#line 3924 "util/configparser.c" +#line 3976 "util/configparser.c" break; - case 396: /* server_ssl_port: VAR_SSL_PORT STRING_ARG */ -#line 1087 "util/configparser.y" + case 397: /* server_ssl_port: VAR_SSL_PORT STRING_ARG */ +#line 1094 "util/configparser.y" { OUTYY(("P(server_ssl_port:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -3932,21 +3984,21 @@ yyreduce: else cfg_parser->cfg->ssl_port = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 3936 "util/configparser.c" +#line 3988 "util/configparser.c" break; - case 397: /* server_tls_cert_bundle: VAR_TLS_CERT_BUNDLE STRING_ARG */ -#line 1096 "util/configparser.y" + case 398: /* server_tls_cert_bundle: VAR_TLS_CERT_BUNDLE STRING_ARG */ +#line 1103 "util/configparser.y" { OUTYY(("P(server_tls_cert_bundle:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->tls_cert_bundle); cfg_parser->cfg->tls_cert_bundle = (yyvsp[0].str); } -#line 3946 "util/configparser.c" +#line 3998 "util/configparser.c" break; - case 398: /* server_tls_win_cert: VAR_TLS_WIN_CERT STRING_ARG */ -#line 1103 "util/configparser.y" + case 399: /* server_tls_win_cert: VAR_TLS_WIN_CERT STRING_ARG */ +#line 1110 "util/configparser.y" { OUTYY(("P(server_tls_win_cert:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -3954,53 +4006,53 @@ yyreduce: else cfg_parser->cfg->tls_win_cert = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 3958 "util/configparser.c" +#line 4010 "util/configparser.c" break; - case 399: /* server_tls_additional_port: VAR_TLS_ADDITIONAL_PORT STRING_ARG */ -#line 1112 "util/configparser.y" + case 400: /* server_tls_additional_port: VAR_TLS_ADDITIONAL_PORT STRING_ARG */ +#line 1119 "util/configparser.y" { OUTYY(("P(server_tls_additional_port:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->tls_additional_port, (yyvsp[0].str))) yyerror("out of memory"); } -#line 3969 "util/configparser.c" +#line 4021 "util/configparser.c" break; - case 400: /* server_tls_ciphers: VAR_TLS_CIPHERS STRING_ARG */ -#line 1120 "util/configparser.y" + case 401: /* server_tls_ciphers: VAR_TLS_CIPHERS STRING_ARG */ +#line 1127 "util/configparser.y" { OUTYY(("P(server_tls_ciphers:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->tls_ciphers); cfg_parser->cfg->tls_ciphers = (yyvsp[0].str); } -#line 3979 "util/configparser.c" +#line 4031 "util/configparser.c" break; - case 401: /* server_tls_ciphersuites: VAR_TLS_CIPHERSUITES STRING_ARG */ -#line 1127 "util/configparser.y" + case 402: /* server_tls_ciphersuites: VAR_TLS_CIPHERSUITES STRING_ARG */ +#line 1134 "util/configparser.y" { OUTYY(("P(server_tls_ciphersuites:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->tls_ciphersuites); cfg_parser->cfg->tls_ciphersuites = (yyvsp[0].str); } -#line 3989 "util/configparser.c" +#line 4041 "util/configparser.c" break; - case 402: /* server_tls_session_ticket_keys: VAR_TLS_SESSION_TICKET_KEYS STRING_ARG */ -#line 1134 "util/configparser.y" + case 403: /* server_tls_session_ticket_keys: VAR_TLS_SESSION_TICKET_KEYS STRING_ARG */ +#line 1141 "util/configparser.y" { OUTYY(("P(server_tls_session_ticket_keys:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_append(&cfg_parser->cfg->tls_session_ticket_keys, (yyvsp[0].str))) yyerror("out of memory"); } -#line 4000 "util/configparser.c" +#line 4052 "util/configparser.c" break; - case 403: /* server_tls_use_sni: VAR_TLS_USE_SNI STRING_ARG */ -#line 1142 "util/configparser.y" + case 404: /* server_tls_use_sni: VAR_TLS_USE_SNI STRING_ARG */ +#line 1149 "util/configparser.y" { OUTYY(("P(server_tls_use_sni:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4008,11 +4060,11 @@ yyreduce: else cfg_parser->cfg->tls_use_sni = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4012 "util/configparser.c" +#line 4064 "util/configparser.c" break; - case 404: /* server_https_port: VAR_HTTPS_PORT STRING_ARG */ -#line 1151 "util/configparser.y" + case 405: /* server_https_port: VAR_HTTPS_PORT STRING_ARG */ +#line 1158 "util/configparser.y" { OUTYY(("P(server_https_port:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -4020,11 +4072,11 @@ yyreduce: else cfg_parser->cfg->https_port = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4024 "util/configparser.c" +#line 4076 "util/configparser.c" break; - case 405: /* server_http_endpoint: VAR_HTTP_ENDPOINT STRING_ARG */ -#line 1159 "util/configparser.y" + case 406: /* server_http_endpoint: VAR_HTTP_ENDPOINT STRING_ARG */ +#line 1166 "util/configparser.y" { OUTYY(("P(server_http_endpoint:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->http_endpoint); @@ -4040,11 +4092,11 @@ yyreduce: cfg_parser->cfg->http_endpoint = (yyvsp[0].str); } } -#line 4044 "util/configparser.c" +#line 4096 "util/configparser.c" break; - case 406: /* server_http_max_streams: VAR_HTTP_MAX_STREAMS STRING_ARG */ -#line 1175 "util/configparser.y" + case 407: /* server_http_max_streams: VAR_HTTP_MAX_STREAMS STRING_ARG */ +#line 1182 "util/configparser.y" { OUTYY(("P(server_http_max_streams:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4052,11 +4104,11 @@ yyreduce: else cfg_parser->cfg->http_max_streams = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4056 "util/configparser.c" +#line 4108 "util/configparser.c" break; - case 407: /* server_http_query_buffer_size: VAR_HTTP_QUERY_BUFFER_SIZE STRING_ARG */ -#line 1183 "util/configparser.y" + case 408: /* server_http_query_buffer_size: VAR_HTTP_QUERY_BUFFER_SIZE STRING_ARG */ +#line 1190 "util/configparser.y" { OUTYY(("P(server_http_query_buffer_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), @@ -4064,11 +4116,11 @@ yyreduce: yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 4068 "util/configparser.c" +#line 4120 "util/configparser.c" break; - case 408: /* server_http_response_buffer_size: VAR_HTTP_RESPONSE_BUFFER_SIZE STRING_ARG */ -#line 1191 "util/configparser.y" + case 409: /* server_http_response_buffer_size: VAR_HTTP_RESPONSE_BUFFER_SIZE STRING_ARG */ +#line 1198 "util/configparser.y" { OUTYY(("P(server_http_response_buffer_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), @@ -4076,11 +4128,11 @@ yyreduce: yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 4080 "util/configparser.c" +#line 4132 "util/configparser.c" break; - case 409: /* server_http_nodelay: VAR_HTTP_NODELAY STRING_ARG */ -#line 1199 "util/configparser.y" + case 410: /* server_http_nodelay: VAR_HTTP_NODELAY STRING_ARG */ +#line 1206 "util/configparser.y" { OUTYY(("P(server_http_nodelay:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4088,11 +4140,11 @@ yyreduce: else cfg_parser->cfg->http_nodelay = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4092 "util/configparser.c" +#line 4144 "util/configparser.c" break; - case 410: /* server_http_notls_downstream: VAR_HTTP_NOTLS_DOWNSTREAM STRING_ARG */ -#line 1207 "util/configparser.y" + case 411: /* server_http_notls_downstream: VAR_HTTP_NOTLS_DOWNSTREAM STRING_ARG */ +#line 1214 "util/configparser.y" { OUTYY(("P(server_http_notls_downstream:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4100,11 +4152,11 @@ yyreduce: else cfg_parser->cfg->http_notls_downstream = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4104 "util/configparser.c" +#line 4156 "util/configparser.c" break; - case 411: /* server_quic_port: VAR_QUIC_PORT STRING_ARG */ -#line 1215 "util/configparser.y" + case 412: /* server_quic_port: VAR_QUIC_PORT STRING_ARG */ +#line 1222 "util/configparser.y" { OUTYY(("P(server_quic_port:%s)\n", (yyvsp[0].str))); #ifndef HAVE_NGTCP2 @@ -4117,22 +4169,22 @@ yyreduce: else cfg_parser->cfg->quic_port = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4121 "util/configparser.c" +#line 4173 "util/configparser.c" break; - case 412: /* server_quic_size: VAR_QUIC_SIZE STRING_ARG */ -#line 1228 "util/configparser.y" + case 413: /* server_quic_size: VAR_QUIC_SIZE STRING_ARG */ +#line 1235 "util/configparser.y" { OUTYY(("P(server_quic_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->quic_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 4132 "util/configparser.c" +#line 4184 "util/configparser.c" break; - case 413: /* server_use_systemd: VAR_USE_SYSTEMD STRING_ARG */ -#line 1235 "util/configparser.y" + case 414: /* server_use_systemd: VAR_USE_SYSTEMD STRING_ARG */ +#line 1242 "util/configparser.y" { OUTYY(("P(server_use_systemd:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4140,11 +4192,11 @@ yyreduce: else cfg_parser->cfg->use_systemd = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4144 "util/configparser.c" +#line 4196 "util/configparser.c" break; - case 414: /* server_do_daemonize: VAR_DO_DAEMONIZE STRING_ARG */ -#line 1244 "util/configparser.y" + case 415: /* server_do_daemonize: VAR_DO_DAEMONIZE STRING_ARG */ +#line 1251 "util/configparser.y" { OUTYY(("P(server_do_daemonize:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4152,11 +4204,11 @@ yyreduce: else cfg_parser->cfg->do_daemonize = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4156 "util/configparser.c" +#line 4208 "util/configparser.c" break; - case 415: /* server_use_syslog: VAR_USE_SYSLOG STRING_ARG */ -#line 1253 "util/configparser.y" + case 416: /* server_use_syslog: VAR_USE_SYSLOG STRING_ARG */ +#line 1260 "util/configparser.y" { OUTYY(("P(server_use_syslog:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4169,11 +4221,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 4173 "util/configparser.c" +#line 4225 "util/configparser.c" break; - case 416: /* server_log_time_ascii: VAR_LOG_TIME_ASCII STRING_ARG */ -#line 1267 "util/configparser.y" + case 417: /* server_log_time_ascii: VAR_LOG_TIME_ASCII STRING_ARG */ +#line 1274 "util/configparser.y" { OUTYY(("P(server_log_time_ascii:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4181,11 +4233,11 @@ yyreduce: else cfg_parser->cfg->log_time_ascii = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4185 "util/configparser.c" +#line 4237 "util/configparser.c" break; - case 417: /* server_log_time_iso: VAR_LOG_TIME_ISO STRING_ARG */ -#line 1276 "util/configparser.y" + case 418: /* server_log_time_iso: VAR_LOG_TIME_ISO STRING_ARG */ +#line 1283 "util/configparser.y" { OUTYY(("P(server_log_time_iso:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4193,11 +4245,11 @@ yyreduce: else cfg_parser->cfg->log_time_iso = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4197 "util/configparser.c" +#line 4249 "util/configparser.c" break; - case 418: /* server_log_queries: VAR_LOG_QUERIES STRING_ARG */ -#line 1285 "util/configparser.y" + case 419: /* server_log_queries: VAR_LOG_QUERIES STRING_ARG */ +#line 1292 "util/configparser.y" { OUTYY(("P(server_log_queries:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4205,11 +4257,11 @@ yyreduce: else cfg_parser->cfg->log_queries = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4209 "util/configparser.c" +#line 4261 "util/configparser.c" break; - case 419: /* server_log_replies: VAR_LOG_REPLIES STRING_ARG */ -#line 1294 "util/configparser.y" + case 420: /* server_log_replies: VAR_LOG_REPLIES STRING_ARG */ +#line 1301 "util/configparser.y" { OUTYY(("P(server_log_replies:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4217,11 +4269,11 @@ yyreduce: else cfg_parser->cfg->log_replies = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4221 "util/configparser.c" +#line 4273 "util/configparser.c" break; - case 420: /* server_log_tag_queryreply: VAR_LOG_TAG_QUERYREPLY STRING_ARG */ -#line 1303 "util/configparser.y" + case 421: /* server_log_tag_queryreply: VAR_LOG_TAG_QUERYREPLY STRING_ARG */ +#line 1310 "util/configparser.y" { OUTYY(("P(server_log_tag_queryreply:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4229,11 +4281,11 @@ yyreduce: else cfg_parser->cfg->log_tag_queryreply = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4233 "util/configparser.c" +#line 4285 "util/configparser.c" break; - case 421: /* server_log_servfail: VAR_LOG_SERVFAIL STRING_ARG */ -#line 1312 "util/configparser.y" + case 422: /* server_log_servfail: VAR_LOG_SERVFAIL STRING_ARG */ +#line 1319 "util/configparser.y" { OUTYY(("P(server_log_servfail:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4241,11 +4293,11 @@ yyreduce: else cfg_parser->cfg->log_servfail = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4245 "util/configparser.c" +#line 4297 "util/configparser.c" break; - case 422: /* server_log_destaddr: VAR_LOG_DESTADDR STRING_ARG */ -#line 1321 "util/configparser.y" + case 423: /* server_log_destaddr: VAR_LOG_DESTADDR STRING_ARG */ +#line 1328 "util/configparser.y" { OUTYY(("P(server_log_destaddr:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4253,11 +4305,11 @@ yyreduce: else cfg_parser->cfg->log_destaddr = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4257 "util/configparser.c" +#line 4309 "util/configparser.c" break; - case 423: /* server_log_local_actions: VAR_LOG_LOCAL_ACTIONS STRING_ARG */ -#line 1330 "util/configparser.y" + case 424: /* server_log_local_actions: VAR_LOG_LOCAL_ACTIONS STRING_ARG */ +#line 1337 "util/configparser.y" { OUTYY(("P(server_log_local_actions:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4265,31 +4317,31 @@ yyreduce: else cfg_parser->cfg->log_local_actions = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4269 "util/configparser.c" +#line 4321 "util/configparser.c" break; - case 424: /* server_chroot: VAR_CHROOT STRING_ARG */ -#line 1339 "util/configparser.y" + case 425: /* server_chroot: VAR_CHROOT STRING_ARG */ +#line 1346 "util/configparser.y" { OUTYY(("P(server_chroot:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->chrootdir); cfg_parser->cfg->chrootdir = (yyvsp[0].str); } -#line 4279 "util/configparser.c" +#line 4331 "util/configparser.c" break; - case 425: /* server_username: VAR_USERNAME STRING_ARG */ -#line 1346 "util/configparser.y" + case 426: /* server_username: VAR_USERNAME STRING_ARG */ +#line 1353 "util/configparser.y" { OUTYY(("P(server_username:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->username); cfg_parser->cfg->username = (yyvsp[0].str); } -#line 4289 "util/configparser.c" +#line 4341 "util/configparser.c" break; - case 426: /* server_directory: VAR_DIRECTORY STRING_ARG */ -#line 1353 "util/configparser.y" + case 427: /* server_directory: VAR_DIRECTORY STRING_ARG */ +#line 1360 "util/configparser.y" { OUTYY(("P(server_directory:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->directory); @@ -4314,105 +4366,105 @@ yyreduce: } } } -#line 4318 "util/configparser.c" +#line 4370 "util/configparser.c" break; - case 427: /* server_logfile: VAR_LOGFILE STRING_ARG */ -#line 1379 "util/configparser.y" + case 428: /* server_logfile: VAR_LOGFILE STRING_ARG */ +#line 1386 "util/configparser.y" { OUTYY(("P(server_logfile:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->logfile); cfg_parser->cfg->logfile = (yyvsp[0].str); cfg_parser->cfg->use_syslog = 0; } -#line 4329 "util/configparser.c" +#line 4381 "util/configparser.c" break; - case 428: /* server_pidfile: VAR_PIDFILE STRING_ARG */ -#line 1387 "util/configparser.y" + case 429: /* server_pidfile: VAR_PIDFILE STRING_ARG */ +#line 1394 "util/configparser.y" { OUTYY(("P(server_pidfile:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->pidfile); cfg_parser->cfg->pidfile = (yyvsp[0].str); } -#line 4339 "util/configparser.c" +#line 4391 "util/configparser.c" break; - case 429: /* server_root_hints: VAR_ROOT_HINTS STRING_ARG */ -#line 1394 "util/configparser.y" + case 430: /* server_root_hints: VAR_ROOT_HINTS STRING_ARG */ +#line 1401 "util/configparser.y" { OUTYY(("P(server_root_hints:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->root_hints, (yyvsp[0].str))) yyerror("out of memory"); } -#line 4349 "util/configparser.c" +#line 4401 "util/configparser.c" break; - case 430: /* server_dlv_anchor_file: VAR_DLV_ANCHOR_FILE STRING_ARG */ -#line 1401 "util/configparser.y" + case 431: /* server_dlv_anchor_file: VAR_DLV_ANCHOR_FILE STRING_ARG */ +#line 1408 "util/configparser.y" { OUTYY(("P(server_dlv_anchor_file:%s)\n", (yyvsp[0].str))); log_warn("option dlv-anchor-file ignored: DLV is decommissioned"); free((yyvsp[0].str)); } -#line 4359 "util/configparser.c" +#line 4411 "util/configparser.c" break; - case 431: /* server_dlv_anchor: VAR_DLV_ANCHOR STRING_ARG */ -#line 1408 "util/configparser.y" + case 432: /* server_dlv_anchor: VAR_DLV_ANCHOR STRING_ARG */ +#line 1415 "util/configparser.y" { OUTYY(("P(server_dlv_anchor:%s)\n", (yyvsp[0].str))); log_warn("option dlv-anchor ignored: DLV is decommissioned"); free((yyvsp[0].str)); } -#line 4369 "util/configparser.c" +#line 4421 "util/configparser.c" break; - case 432: /* server_auto_trust_anchor_file: VAR_AUTO_TRUST_ANCHOR_FILE STRING_ARG */ -#line 1415 "util/configparser.y" + case 433: /* server_auto_trust_anchor_file: VAR_AUTO_TRUST_ANCHOR_FILE STRING_ARG */ +#line 1422 "util/configparser.y" { OUTYY(("P(server_auto_trust_anchor_file:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg-> auto_trust_anchor_file_list, (yyvsp[0].str))) yyerror("out of memory"); } -#line 4380 "util/configparser.c" +#line 4432 "util/configparser.c" break; - case 433: /* server_trust_anchor_file: VAR_TRUST_ANCHOR_FILE STRING_ARG */ -#line 1423 "util/configparser.y" + case 434: /* server_trust_anchor_file: VAR_TRUST_ANCHOR_FILE STRING_ARG */ +#line 1430 "util/configparser.y" { OUTYY(("P(server_trust_anchor_file:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg-> trust_anchor_file_list, (yyvsp[0].str))) yyerror("out of memory"); } -#line 4391 "util/configparser.c" +#line 4443 "util/configparser.c" break; - case 434: /* server_trusted_keys_file: VAR_TRUSTED_KEYS_FILE STRING_ARG */ -#line 1431 "util/configparser.y" + case 435: /* server_trusted_keys_file: VAR_TRUSTED_KEYS_FILE STRING_ARG */ +#line 1438 "util/configparser.y" { OUTYY(("P(server_trusted_keys_file:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg-> trusted_keys_file_list, (yyvsp[0].str))) yyerror("out of memory"); } -#line 4402 "util/configparser.c" +#line 4454 "util/configparser.c" break; - case 435: /* server_trust_anchor: VAR_TRUST_ANCHOR STRING_ARG */ -#line 1439 "util/configparser.y" + case 436: /* server_trust_anchor: VAR_TRUST_ANCHOR STRING_ARG */ +#line 1446 "util/configparser.y" { OUTYY(("P(server_trust_anchor:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->trust_anchor_list, (yyvsp[0].str))) yyerror("out of memory"); } -#line 4412 "util/configparser.c" +#line 4464 "util/configparser.c" break; - case 436: /* server_trust_anchor_signaling: VAR_TRUST_ANCHOR_SIGNALING STRING_ARG */ -#line 1446 "util/configparser.y" + case 437: /* server_trust_anchor_signaling: VAR_TRUST_ANCHOR_SIGNALING STRING_ARG */ +#line 1453 "util/configparser.y" { OUTYY(("P(server_trust_anchor_signaling:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4422,11 +4474,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4426 "util/configparser.c" +#line 4478 "util/configparser.c" break; - case 437: /* server_root_key_sentinel: VAR_ROOT_KEY_SENTINEL STRING_ARG */ -#line 1457 "util/configparser.y" + case 438: /* server_root_key_sentinel: VAR_ROOT_KEY_SENTINEL STRING_ARG */ +#line 1464 "util/configparser.y" { OUTYY(("P(server_root_key_sentinel:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4436,21 +4488,21 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4440 "util/configparser.c" +#line 4492 "util/configparser.c" break; - case 438: /* server_domain_insecure: VAR_DOMAIN_INSECURE STRING_ARG */ -#line 1468 "util/configparser.y" + case 439: /* server_domain_insecure: VAR_DOMAIN_INSECURE STRING_ARG */ +#line 1475 "util/configparser.y" { OUTYY(("P(server_domain_insecure:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->domain_insecure, (yyvsp[0].str))) yyerror("out of memory"); } -#line 4450 "util/configparser.c" +#line 4502 "util/configparser.c" break; - case 439: /* server_hide_identity: VAR_HIDE_IDENTITY STRING_ARG */ -#line 1475 "util/configparser.y" + case 440: /* server_hide_identity: VAR_HIDE_IDENTITY STRING_ARG */ +#line 1482 "util/configparser.y" { OUTYY(("P(server_hide_identity:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4458,11 +4510,11 @@ yyreduce: else cfg_parser->cfg->hide_identity = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4462 "util/configparser.c" +#line 4514 "util/configparser.c" break; - case 440: /* server_hide_version: VAR_HIDE_VERSION STRING_ARG */ -#line 1484 "util/configparser.y" + case 441: /* server_hide_version: VAR_HIDE_VERSION STRING_ARG */ +#line 1491 "util/configparser.y" { OUTYY(("P(server_hide_version:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4470,11 +4522,11 @@ yyreduce: else cfg_parser->cfg->hide_version = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4474 "util/configparser.c" +#line 4526 "util/configparser.c" break; - case 441: /* server_hide_trustanchor: VAR_HIDE_TRUSTANCHOR STRING_ARG */ -#line 1493 "util/configparser.y" + case 442: /* server_hide_trustanchor: VAR_HIDE_TRUSTANCHOR STRING_ARG */ +#line 1500 "util/configparser.y" { OUTYY(("P(server_hide_trustanchor:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4482,11 +4534,11 @@ yyreduce: else cfg_parser->cfg->hide_trustanchor = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4486 "util/configparser.c" +#line 4538 "util/configparser.c" break; - case 442: /* server_hide_http_user_agent: VAR_HIDE_HTTP_USER_AGENT STRING_ARG */ -#line 1502 "util/configparser.y" + case 443: /* server_hide_http_user_agent: VAR_HIDE_HTTP_USER_AGENT STRING_ARG */ +#line 1509 "util/configparser.y" { OUTYY(("P(server_hide_user_agent:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4494,41 +4546,41 @@ yyreduce: else cfg_parser->cfg->hide_http_user_agent = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4498 "util/configparser.c" +#line 4550 "util/configparser.c" break; - case 443: /* server_identity: VAR_IDENTITY STRING_ARG */ -#line 1511 "util/configparser.y" + case 444: /* server_identity: VAR_IDENTITY STRING_ARG */ +#line 1518 "util/configparser.y" { OUTYY(("P(server_identity:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->identity); cfg_parser->cfg->identity = (yyvsp[0].str); } -#line 4508 "util/configparser.c" +#line 4560 "util/configparser.c" break; - case 444: /* server_version: VAR_VERSION STRING_ARG */ -#line 1518 "util/configparser.y" + case 445: /* server_version: VAR_VERSION STRING_ARG */ +#line 1525 "util/configparser.y" { OUTYY(("P(server_version:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->version); cfg_parser->cfg->version = (yyvsp[0].str); } -#line 4518 "util/configparser.c" +#line 4570 "util/configparser.c" break; - case 445: /* server_http_user_agent: VAR_HTTP_USER_AGENT STRING_ARG */ -#line 1525 "util/configparser.y" + case 446: /* server_http_user_agent: VAR_HTTP_USER_AGENT STRING_ARG */ +#line 1532 "util/configparser.y" { OUTYY(("P(server_http_user_agent:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->http_user_agent); cfg_parser->cfg->http_user_agent = (yyvsp[0].str); } -#line 4528 "util/configparser.c" +#line 4580 "util/configparser.c" break; - case 446: /* server_nsid: VAR_NSID STRING_ARG */ -#line 1532 "util/configparser.y" + case 447: /* server_nsid: VAR_NSID STRING_ARG */ +#line 1539 "util/configparser.y" { OUTYY(("P(server_nsid:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->nsid_cfg_str); @@ -4543,33 +4595,33 @@ yyreduce: yyerror("the NSID must be either a hex string or an " "ascii character string prepended with ascii_."); } -#line 4547 "util/configparser.c" +#line 4599 "util/configparser.c" break; - case 447: /* server_so_rcvbuf: VAR_SO_RCVBUF STRING_ARG */ -#line 1548 "util/configparser.y" + case 448: /* server_so_rcvbuf: VAR_SO_RCVBUF STRING_ARG */ +#line 1555 "util/configparser.y" { OUTYY(("P(server_so_rcvbuf:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->so_rcvbuf)) yyerror("buffer size expected"); free((yyvsp[0].str)); } -#line 4558 "util/configparser.c" +#line 4610 "util/configparser.c" break; - case 448: /* server_so_sndbuf: VAR_SO_SNDBUF STRING_ARG */ -#line 1556 "util/configparser.y" + case 449: /* server_so_sndbuf: VAR_SO_SNDBUF STRING_ARG */ +#line 1563 "util/configparser.y" { OUTYY(("P(server_so_sndbuf:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->so_sndbuf)) yyerror("buffer size expected"); free((yyvsp[0].str)); } -#line 4569 "util/configparser.c" +#line 4621 "util/configparser.c" break; - case 449: /* server_so_reuseport: VAR_SO_REUSEPORT STRING_ARG */ -#line 1564 "util/configparser.y" + case 450: /* server_so_reuseport: VAR_SO_REUSEPORT STRING_ARG */ +#line 1571 "util/configparser.y" { OUTYY(("P(server_so_reuseport:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4578,11 +4630,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4582 "util/configparser.c" +#line 4634 "util/configparser.c" break; - case 450: /* server_ip_transparent: VAR_IP_TRANSPARENT STRING_ARG */ -#line 1574 "util/configparser.y" + case 451: /* server_ip_transparent: VAR_IP_TRANSPARENT STRING_ARG */ +#line 1581 "util/configparser.y" { OUTYY(("P(server_ip_transparent:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4591,11 +4643,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4595 "util/configparser.c" +#line 4647 "util/configparser.c" break; - case 451: /* server_ip_freebind: VAR_IP_FREEBIND STRING_ARG */ -#line 1584 "util/configparser.y" + case 452: /* server_ip_freebind: VAR_IP_FREEBIND STRING_ARG */ +#line 1591 "util/configparser.y" { OUTYY(("P(server_ip_freebind:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4604,11 +4656,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4608 "util/configparser.c" +#line 4660 "util/configparser.c" break; - case 452: /* server_ip_dscp: VAR_IP_DSCP STRING_ARG */ -#line 1594 "util/configparser.y" + case 453: /* server_ip_dscp: VAR_IP_DSCP STRING_ARG */ +#line 1601 "util/configparser.y" { OUTYY(("P(server_ip_dscp:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4621,22 +4673,22 @@ yyreduce: cfg_parser->cfg->ip_dscp = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4625 "util/configparser.c" +#line 4677 "util/configparser.c" break; - case 453: /* server_stream_wait_size: VAR_STREAM_WAIT_SIZE STRING_ARG */ -#line 1608 "util/configparser.y" + case 454: /* server_stream_wait_size: VAR_STREAM_WAIT_SIZE STRING_ARG */ +#line 1615 "util/configparser.y" { OUTYY(("P(server_stream_wait_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->stream_wait_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 4636 "util/configparser.c" +#line 4688 "util/configparser.c" break; - case 454: /* server_edns_buffer_size: VAR_EDNS_BUFFER_SIZE STRING_ARG */ -#line 1616 "util/configparser.y" + case 455: /* server_edns_buffer_size: VAR_EDNS_BUFFER_SIZE STRING_ARG */ +#line 1623 "util/configparser.y" { OUTYY(("P(server_edns_buffer_size:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -4648,11 +4700,11 @@ yyreduce: else cfg_parser->cfg->edns_buffer_size = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4652 "util/configparser.c" +#line 4704 "util/configparser.c" break; - case 455: /* server_msg_buffer_size: VAR_MSG_BUFFER_SIZE STRING_ARG */ -#line 1629 "util/configparser.y" + case 456: /* server_msg_buffer_size: VAR_MSG_BUFFER_SIZE STRING_ARG */ +#line 1636 "util/configparser.y" { OUTYY(("P(server_msg_buffer_size:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -4662,22 +4714,22 @@ yyreduce: else cfg_parser->cfg->msg_buffer_size = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4666 "util/configparser.c" +#line 4718 "util/configparser.c" break; - case 456: /* server_msg_cache_size: VAR_MSG_CACHE_SIZE STRING_ARG */ -#line 1640 "util/configparser.y" + case 457: /* server_msg_cache_size: VAR_MSG_CACHE_SIZE STRING_ARG */ +#line 1647 "util/configparser.y" { OUTYY(("P(server_msg_cache_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->msg_cache_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 4677 "util/configparser.c" +#line 4729 "util/configparser.c" break; - case 457: /* server_msg_cache_slabs: VAR_MSG_CACHE_SLABS STRING_ARG */ -#line 1648 "util/configparser.y" + case 458: /* server_msg_cache_slabs: VAR_MSG_CACHE_SLABS STRING_ARG */ +#line 1655 "util/configparser.y" { OUTYY(("P(server_msg_cache_slabs:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) { @@ -4689,11 +4741,11 @@ yyreduce: } free((yyvsp[0].str)); } -#line 4693 "util/configparser.c" +#line 4745 "util/configparser.c" break; - case 458: /* server_num_queries_per_thread: VAR_NUM_QUERIES_PER_THREAD STRING_ARG */ -#line 1661 "util/configparser.y" + case 459: /* server_num_queries_per_thread: VAR_NUM_QUERIES_PER_THREAD STRING_ARG */ +#line 1668 "util/configparser.y" { OUTYY(("P(server_num_queries_per_thread:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -4701,11 +4753,11 @@ yyreduce: else cfg_parser->cfg->num_queries_per_thread = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4705 "util/configparser.c" +#line 4757 "util/configparser.c" break; - case 459: /* server_jostle_timeout: VAR_JOSTLE_TIMEOUT STRING_ARG */ -#line 1670 "util/configparser.y" + case 460: /* server_jostle_timeout: VAR_JOSTLE_TIMEOUT STRING_ARG */ +#line 1677 "util/configparser.y" { OUTYY(("P(server_jostle_timeout:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4713,11 +4765,11 @@ yyreduce: else cfg_parser->cfg->jostle_time = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4717 "util/configparser.c" +#line 4769 "util/configparser.c" break; - case 460: /* server_delay_close: VAR_DELAY_CLOSE STRING_ARG */ -#line 1679 "util/configparser.y" + case 461: /* server_delay_close: VAR_DELAY_CLOSE STRING_ARG */ +#line 1686 "util/configparser.y" { OUTYY(("P(server_delay_close:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4725,11 +4777,11 @@ yyreduce: else cfg_parser->cfg->delay_close = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4729 "util/configparser.c" +#line 4781 "util/configparser.c" break; - case 461: /* server_udp_connect: VAR_UDP_CONNECT STRING_ARG */ -#line 1688 "util/configparser.y" + case 462: /* server_udp_connect: VAR_UDP_CONNECT STRING_ARG */ +#line 1695 "util/configparser.y" { OUTYY(("P(server_udp_connect:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4737,11 +4789,11 @@ yyreduce: else cfg_parser->cfg->udp_connect = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4741 "util/configparser.c" +#line 4793 "util/configparser.c" break; - case 462: /* server_unblock_lan_zones: VAR_UNBLOCK_LAN_ZONES STRING_ARG */ -#line 1697 "util/configparser.y" + case 463: /* server_unblock_lan_zones: VAR_UNBLOCK_LAN_ZONES STRING_ARG */ +#line 1704 "util/configparser.y" { OUTYY(("P(server_unblock_lan_zones:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4750,11 +4802,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4754 "util/configparser.c" +#line 4806 "util/configparser.c" break; - case 463: /* server_insecure_lan_zones: VAR_INSECURE_LAN_ZONES STRING_ARG */ -#line 1707 "util/configparser.y" + case 464: /* server_insecure_lan_zones: VAR_INSECURE_LAN_ZONES STRING_ARG */ +#line 1714 "util/configparser.y" { OUTYY(("P(server_insecure_lan_zones:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4763,22 +4815,22 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4767 "util/configparser.c" +#line 4819 "util/configparser.c" break; - case 464: /* server_rrset_cache_size: VAR_RRSET_CACHE_SIZE STRING_ARG */ -#line 1717 "util/configparser.y" + case 465: /* server_rrset_cache_size: VAR_RRSET_CACHE_SIZE STRING_ARG */ +#line 1724 "util/configparser.y" { OUTYY(("P(server_rrset_cache_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->rrset_cache_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 4778 "util/configparser.c" +#line 4830 "util/configparser.c" break; - case 465: /* server_rrset_cache_slabs: VAR_RRSET_CACHE_SLABS STRING_ARG */ -#line 1725 "util/configparser.y" + case 466: /* server_rrset_cache_slabs: VAR_RRSET_CACHE_SLABS STRING_ARG */ +#line 1732 "util/configparser.y" { OUTYY(("P(server_rrset_cache_slabs:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) { @@ -4790,11 +4842,11 @@ yyreduce: } free((yyvsp[0].str)); } -#line 4794 "util/configparser.c" +#line 4846 "util/configparser.c" break; - case 466: /* server_infra_host_ttl: VAR_INFRA_HOST_TTL STRING_ARG */ -#line 1738 "util/configparser.y" + case 467: /* server_infra_host_ttl: VAR_INFRA_HOST_TTL STRING_ARG */ +#line 1745 "util/configparser.y" { OUTYY(("P(server_infra_host_ttl:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4802,22 +4854,22 @@ yyreduce: else cfg_parser->cfg->host_ttl = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4806 "util/configparser.c" +#line 4858 "util/configparser.c" break; - case 467: /* server_infra_lame_ttl: VAR_INFRA_LAME_TTL STRING_ARG */ -#line 1747 "util/configparser.y" + case 468: /* server_infra_lame_ttl: VAR_INFRA_LAME_TTL STRING_ARG */ +#line 1754 "util/configparser.y" { OUTYY(("P(server_infra_lame_ttl:%s)\n", (yyvsp[0].str))); verbose(VERB_DETAIL, "ignored infra-lame-ttl: %s (option " "removed, use infra-host-ttl)", (yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4817 "util/configparser.c" +#line 4869 "util/configparser.c" break; - case 468: /* server_infra_cache_numhosts: VAR_INFRA_CACHE_NUMHOSTS STRING_ARG */ -#line 1755 "util/configparser.y" + case 469: /* server_infra_cache_numhosts: VAR_INFRA_CACHE_NUMHOSTS STRING_ARG */ +#line 1762 "util/configparser.y" { OUTYY(("P(server_infra_cache_numhosts:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -4825,22 +4877,22 @@ yyreduce: else cfg_parser->cfg->infra_cache_numhosts = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4829 "util/configparser.c" +#line 4881 "util/configparser.c" break; - case 469: /* server_infra_cache_lame_size: VAR_INFRA_CACHE_LAME_SIZE STRING_ARG */ -#line 1764 "util/configparser.y" + case 470: /* server_infra_cache_lame_size: VAR_INFRA_CACHE_LAME_SIZE STRING_ARG */ +#line 1771 "util/configparser.y" { OUTYY(("P(server_infra_cache_lame_size:%s)\n", (yyvsp[0].str))); verbose(VERB_DETAIL, "ignored infra-cache-lame-size: %s " "(option removed, use infra-cache-numhosts)", (yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4840 "util/configparser.c" +#line 4892 "util/configparser.c" break; - case 470: /* server_infra_cache_slabs: VAR_INFRA_CACHE_SLABS STRING_ARG */ -#line 1772 "util/configparser.y" + case 471: /* server_infra_cache_slabs: VAR_INFRA_CACHE_SLABS STRING_ARG */ +#line 1779 "util/configparser.y" { OUTYY(("P(server_infra_cache_slabs:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) { @@ -4852,11 +4904,11 @@ yyreduce: } free((yyvsp[0].str)); } -#line 4856 "util/configparser.c" +#line 4908 "util/configparser.c" break; - case 471: /* server_infra_cache_min_rtt: VAR_INFRA_CACHE_MIN_RTT STRING_ARG */ -#line 1785 "util/configparser.y" + case 472: /* server_infra_cache_min_rtt: VAR_INFRA_CACHE_MIN_RTT STRING_ARG */ +#line 1792 "util/configparser.y" { OUTYY(("P(server_infra_cache_min_rtt:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4864,11 +4916,11 @@ yyreduce: else cfg_parser->cfg->infra_cache_min_rtt = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4868 "util/configparser.c" +#line 4920 "util/configparser.c" break; - case 472: /* server_infra_cache_max_rtt: VAR_INFRA_CACHE_MAX_RTT STRING_ARG */ -#line 1794 "util/configparser.y" + case 473: /* server_infra_cache_max_rtt: VAR_INFRA_CACHE_MAX_RTT STRING_ARG */ +#line 1801 "util/configparser.y" { OUTYY(("P(server_infra_cache_max_rtt:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -4876,11 +4928,11 @@ yyreduce: else cfg_parser->cfg->infra_cache_max_rtt = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 4880 "util/configparser.c" +#line 4932 "util/configparser.c" break; - case 473: /* server_infra_keep_probing: VAR_INFRA_KEEP_PROBING STRING_ARG */ -#line 1803 "util/configparser.y" + case 474: /* server_infra_keep_probing: VAR_INFRA_KEEP_PROBING STRING_ARG */ +#line 1810 "util/configparser.y" { OUTYY(("P(server_infra_keep_probing:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4889,21 +4941,21 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4893 "util/configparser.c" +#line 4945 "util/configparser.c" break; - case 474: /* server_target_fetch_policy: VAR_TARGET_FETCH_POLICY STRING_ARG */ -#line 1813 "util/configparser.y" + case 475: /* server_target_fetch_policy: VAR_TARGET_FETCH_POLICY STRING_ARG */ +#line 1820 "util/configparser.y" { OUTYY(("P(server_target_fetch_policy:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->target_fetch_policy); cfg_parser->cfg->target_fetch_policy = (yyvsp[0].str); } -#line 4903 "util/configparser.c" +#line 4955 "util/configparser.c" break; - case 475: /* server_harden_short_bufsize: VAR_HARDEN_SHORT_BUFSIZE STRING_ARG */ -#line 1820 "util/configparser.y" + case 476: /* server_harden_short_bufsize: VAR_HARDEN_SHORT_BUFSIZE STRING_ARG */ +#line 1827 "util/configparser.y" { OUTYY(("P(server_harden_short_bufsize:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4912,11 +4964,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4916 "util/configparser.c" +#line 4968 "util/configparser.c" break; - case 476: /* server_harden_large_queries: VAR_HARDEN_LARGE_QUERIES STRING_ARG */ -#line 1830 "util/configparser.y" + case 477: /* server_harden_large_queries: VAR_HARDEN_LARGE_QUERIES STRING_ARG */ +#line 1837 "util/configparser.y" { OUTYY(("P(server_harden_large_queries:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4925,11 +4977,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4929 "util/configparser.c" +#line 4981 "util/configparser.c" break; - case 477: /* server_harden_glue: VAR_HARDEN_GLUE STRING_ARG */ -#line 1840 "util/configparser.y" + case 478: /* server_harden_glue: VAR_HARDEN_GLUE STRING_ARG */ +#line 1847 "util/configparser.y" { OUTYY(("P(server_harden_glue:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4938,11 +4990,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4942 "util/configparser.c" +#line 4994 "util/configparser.c" break; - case 478: /* server_harden_unverified_glue: VAR_HARDEN_UNVERIFIED_GLUE STRING_ARG */ -#line 1850 "util/configparser.y" + case 479: /* server_harden_unverified_glue: VAR_HARDEN_UNVERIFIED_GLUE STRING_ARG */ +#line 1857 "util/configparser.y" { OUTYY(("P(server_harden_unverified_glue:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4951,11 +5003,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4955 "util/configparser.c" +#line 5007 "util/configparser.c" break; - case 479: /* server_harden_dnssec_stripped: VAR_HARDEN_DNSSEC_STRIPPED STRING_ARG */ -#line 1860 "util/configparser.y" + case 480: /* server_harden_dnssec_stripped: VAR_HARDEN_DNSSEC_STRIPPED STRING_ARG */ +#line 1867 "util/configparser.y" { OUTYY(("P(server_harden_dnssec_stripped:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4964,11 +5016,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4968 "util/configparser.c" +#line 5020 "util/configparser.c" break; - case 480: /* server_harden_below_nxdomain: VAR_HARDEN_BELOW_NXDOMAIN STRING_ARG */ -#line 1870 "util/configparser.y" + case 481: /* server_harden_below_nxdomain: VAR_HARDEN_BELOW_NXDOMAIN STRING_ARG */ +#line 1877 "util/configparser.y" { OUTYY(("P(server_harden_below_nxdomain:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4977,11 +5029,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4981 "util/configparser.c" +#line 5033 "util/configparser.c" break; - case 481: /* server_harden_referral_path: VAR_HARDEN_REFERRAL_PATH STRING_ARG */ -#line 1880 "util/configparser.y" + case 482: /* server_harden_referral_path: VAR_HARDEN_REFERRAL_PATH STRING_ARG */ +#line 1887 "util/configparser.y" { OUTYY(("P(server_harden_referral_path:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -4990,11 +5042,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 4994 "util/configparser.c" +#line 5046 "util/configparser.c" break; - case 482: /* server_harden_algo_downgrade: VAR_HARDEN_ALGO_DOWNGRADE STRING_ARG */ -#line 1890 "util/configparser.y" + case 483: /* server_harden_algo_downgrade: VAR_HARDEN_ALGO_DOWNGRADE STRING_ARG */ +#line 1897 "util/configparser.y" { OUTYY(("P(server_harden_algo_downgrade:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5003,11 +5055,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5007 "util/configparser.c" +#line 5059 "util/configparser.c" break; - case 483: /* server_harden_unknown_additional: VAR_HARDEN_UNKNOWN_ADDITIONAL STRING_ARG */ -#line 1900 "util/configparser.y" + case 484: /* server_harden_unknown_additional: VAR_HARDEN_UNKNOWN_ADDITIONAL STRING_ARG */ +#line 1907 "util/configparser.y" { OUTYY(("P(server_harden_unknown_additional:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5016,11 +5068,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5020 "util/configparser.c" +#line 5072 "util/configparser.c" break; - case 484: /* server_use_caps_for_id: VAR_USE_CAPS_FOR_ID STRING_ARG */ -#line 1910 "util/configparser.y" + case 485: /* server_use_caps_for_id: VAR_USE_CAPS_FOR_ID STRING_ARG */ +#line 1917 "util/configparser.y" { OUTYY(("P(server_use_caps_for_id:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5029,41 +5081,41 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5033 "util/configparser.c" +#line 5085 "util/configparser.c" break; - case 485: /* server_caps_whitelist: VAR_CAPS_WHITELIST STRING_ARG */ -#line 1920 "util/configparser.y" + case 486: /* server_caps_whitelist: VAR_CAPS_WHITELIST STRING_ARG */ +#line 1927 "util/configparser.y" { OUTYY(("P(server_caps_whitelist:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->caps_whitelist, (yyvsp[0].str))) yyerror("out of memory"); } -#line 5043 "util/configparser.c" +#line 5095 "util/configparser.c" break; - case 486: /* server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG */ -#line 1927 "util/configparser.y" + case 487: /* server_private_address: VAR_PRIVATE_ADDRESS STRING_ARG */ +#line 1934 "util/configparser.y" { OUTYY(("P(server_private_address:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->private_address, (yyvsp[0].str))) yyerror("out of memory"); } -#line 5053 "util/configparser.c" +#line 5105 "util/configparser.c" break; - case 487: /* server_private_domain: VAR_PRIVATE_DOMAIN STRING_ARG */ -#line 1934 "util/configparser.y" + case 488: /* server_private_domain: VAR_PRIVATE_DOMAIN STRING_ARG */ +#line 1941 "util/configparser.y" { OUTYY(("P(server_private_domain:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->private_domain, (yyvsp[0].str))) yyerror("out of memory"); } -#line 5063 "util/configparser.c" +#line 5115 "util/configparser.c" break; - case 488: /* server_prefetch: VAR_PREFETCH STRING_ARG */ -#line 1941 "util/configparser.y" + case 489: /* server_prefetch: VAR_PREFETCH STRING_ARG */ +#line 1948 "util/configparser.y" { OUTYY(("P(server_prefetch:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5071,11 +5123,11 @@ yyreduce: else cfg_parser->cfg->prefetch = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5075 "util/configparser.c" +#line 5127 "util/configparser.c" break; - case 489: /* server_prefetch_key: VAR_PREFETCH_KEY STRING_ARG */ -#line 1950 "util/configparser.y" + case 490: /* server_prefetch_key: VAR_PREFETCH_KEY STRING_ARG */ +#line 1957 "util/configparser.y" { OUTYY(("P(server_prefetch_key:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5083,11 +5135,11 @@ yyreduce: else cfg_parser->cfg->prefetch_key = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5087 "util/configparser.c" +#line 5139 "util/configparser.c" break; - case 490: /* server_deny_any: VAR_DENY_ANY STRING_ARG */ -#line 1959 "util/configparser.y" + case 491: /* server_deny_any: VAR_DENY_ANY STRING_ARG */ +#line 1966 "util/configparser.y" { OUTYY(("P(server_deny_any:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5095,11 +5147,11 @@ yyreduce: else cfg_parser->cfg->deny_any = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5099 "util/configparser.c" +#line 5151 "util/configparser.c" break; - case 491: /* server_unwanted_reply_threshold: VAR_UNWANTED_REPLY_THRESHOLD STRING_ARG */ -#line 1968 "util/configparser.y" + case 492: /* server_unwanted_reply_threshold: VAR_UNWANTED_REPLY_THRESHOLD STRING_ARG */ +#line 1975 "util/configparser.y" { OUTYY(("P(server_unwanted_reply_threshold:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -5107,21 +5159,21 @@ yyreduce: else cfg_parser->cfg->unwanted_threshold = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5111 "util/configparser.c" +#line 5163 "util/configparser.c" break; - case 492: /* server_do_not_query_address: VAR_DO_NOT_QUERY_ADDRESS STRING_ARG */ -#line 1977 "util/configparser.y" + case 493: /* server_do_not_query_address: VAR_DO_NOT_QUERY_ADDRESS STRING_ARG */ +#line 1984 "util/configparser.y" { OUTYY(("P(server_do_not_query_address:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->donotqueryaddrs, (yyvsp[0].str))) yyerror("out of memory"); } -#line 5121 "util/configparser.c" +#line 5173 "util/configparser.c" break; - case 493: /* server_do_not_query_localhost: VAR_DO_NOT_QUERY_LOCALHOST STRING_ARG */ -#line 1984 "util/configparser.y" + case 494: /* server_do_not_query_localhost: VAR_DO_NOT_QUERY_LOCALHOST STRING_ARG */ +#line 1991 "util/configparser.y" { OUTYY(("P(server_do_not_query_localhost:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5130,22 +5182,22 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5134 "util/configparser.c" +#line 5186 "util/configparser.c" break; - case 494: /* server_access_control: VAR_ACCESS_CONTROL STRING_ARG STRING_ARG */ -#line 1994 "util/configparser.y" + case 495: /* server_access_control: VAR_ACCESS_CONTROL STRING_ARG STRING_ARG */ +#line 2001 "util/configparser.y" { OUTYY(("P(server_access_control:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); validate_acl_action((yyvsp[0].str)); if(!cfg_str2list_insert(&cfg_parser->cfg->acls, (yyvsp[-1].str), (yyvsp[0].str))) fatal_exit("out of memory adding acl"); } -#line 5145 "util/configparser.c" +#line 5197 "util/configparser.c" break; - case 495: /* server_interface_action: VAR_INTERFACE_ACTION STRING_ARG STRING_ARG */ -#line 2002 "util/configparser.y" + case 496: /* server_interface_action: VAR_INTERFACE_ACTION STRING_ARG STRING_ARG */ +#line 2009 "util/configparser.y" { OUTYY(("P(server_interface_action:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); validate_acl_action((yyvsp[0].str)); @@ -5153,21 +5205,21 @@ yyreduce: &cfg_parser->cfg->interface_actions, (yyvsp[-1].str), (yyvsp[0].str))) fatal_exit("out of memory adding acl"); } -#line 5157 "util/configparser.c" +#line 5209 "util/configparser.c" break; - case 496: /* server_module_conf: VAR_MODULE_CONF STRING_ARG */ -#line 2011 "util/configparser.y" + case 497: /* server_module_conf: VAR_MODULE_CONF STRING_ARG */ +#line 2018 "util/configparser.y" { OUTYY(("P(server_module_conf:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->module_conf); cfg_parser->cfg->module_conf = (yyvsp[0].str); } -#line 5167 "util/configparser.c" +#line 5219 "util/configparser.c" break; - case 497: /* server_val_override_date: VAR_VAL_OVERRIDE_DATE STRING_ARG */ -#line 2018 "util/configparser.y" + case 498: /* server_val_override_date: VAR_VAL_OVERRIDE_DATE STRING_ARG */ +#line 2025 "util/configparser.y" { OUTYY(("P(server_val_override_date:%s)\n", (yyvsp[0].str))); if(*(yyvsp[0].str) == '\0' || strcmp((yyvsp[0].str), "0") == 0) { @@ -5184,11 +5236,11 @@ yyreduce: } free((yyvsp[0].str)); } -#line 5188 "util/configparser.c" +#line 5240 "util/configparser.c" break; - case 498: /* server_val_sig_skew_min: VAR_VAL_SIG_SKEW_MIN STRING_ARG */ -#line 2036 "util/configparser.y" + case 499: /* server_val_sig_skew_min: VAR_VAL_SIG_SKEW_MIN STRING_ARG */ +#line 2043 "util/configparser.y" { OUTYY(("P(server_val_sig_skew_min:%s)\n", (yyvsp[0].str))); if(*(yyvsp[0].str) == '\0' || strcmp((yyvsp[0].str), "0") == 0) { @@ -5200,11 +5252,11 @@ yyreduce: } free((yyvsp[0].str)); } -#line 5204 "util/configparser.c" +#line 5256 "util/configparser.c" break; - case 499: /* server_val_sig_skew_max: VAR_VAL_SIG_SKEW_MAX STRING_ARG */ -#line 2049 "util/configparser.y" + case 500: /* server_val_sig_skew_max: VAR_VAL_SIG_SKEW_MAX STRING_ARG */ +#line 2056 "util/configparser.y" { OUTYY(("P(server_val_sig_skew_max:%s)\n", (yyvsp[0].str))); if(*(yyvsp[0].str) == '\0' || strcmp((yyvsp[0].str), "0") == 0) { @@ -5216,11 +5268,11 @@ yyreduce: } free((yyvsp[0].str)); } -#line 5220 "util/configparser.c" +#line 5272 "util/configparser.c" break; - case 500: /* server_val_max_restart: VAR_VAL_MAX_RESTART STRING_ARG */ -#line 2062 "util/configparser.y" + case 501: /* server_val_max_restart: VAR_VAL_MAX_RESTART STRING_ARG */ +#line 2069 "util/configparser.y" { OUTYY(("P(server_val_max_restart:%s)\n", (yyvsp[0].str))); if(*(yyvsp[0].str) == '\0' || strcmp((yyvsp[0].str), "0") == 0) { @@ -5232,11 +5284,11 @@ yyreduce: } free((yyvsp[0].str)); } -#line 5236 "util/configparser.c" +#line 5288 "util/configparser.c" break; - case 501: /* server_cache_max_ttl: VAR_CACHE_MAX_TTL STRING_ARG */ -#line 2075 "util/configparser.y" + case 502: /* server_cache_max_ttl: VAR_CACHE_MAX_TTL STRING_ARG */ +#line 2082 "util/configparser.y" { OUTYY(("P(server_cache_max_ttl:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -5244,11 +5296,11 @@ yyreduce: else cfg_parser->cfg->max_ttl = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5248 "util/configparser.c" +#line 5300 "util/configparser.c" break; - case 502: /* server_cache_max_negative_ttl: VAR_CACHE_MAX_NEGATIVE_TTL STRING_ARG */ -#line 2084 "util/configparser.y" + case 503: /* server_cache_max_negative_ttl: VAR_CACHE_MAX_NEGATIVE_TTL STRING_ARG */ +#line 2091 "util/configparser.y" { OUTYY(("P(server_cache_max_negative_ttl:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -5256,11 +5308,11 @@ yyreduce: else cfg_parser->cfg->max_negative_ttl = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5260 "util/configparser.c" +#line 5312 "util/configparser.c" break; - case 503: /* server_cache_min_negative_ttl: VAR_CACHE_MIN_NEGATIVE_TTL STRING_ARG */ -#line 2093 "util/configparser.y" + case 504: /* server_cache_min_negative_ttl: VAR_CACHE_MIN_NEGATIVE_TTL STRING_ARG */ +#line 2100 "util/configparser.y" { OUTYY(("P(server_cache_min_negative_ttl:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -5268,11 +5320,11 @@ yyreduce: else cfg_parser->cfg->min_negative_ttl = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5272 "util/configparser.c" +#line 5324 "util/configparser.c" break; - case 504: /* server_cache_min_ttl: VAR_CACHE_MIN_TTL STRING_ARG */ -#line 2102 "util/configparser.y" + case 505: /* server_cache_min_ttl: VAR_CACHE_MIN_TTL STRING_ARG */ +#line 2109 "util/configparser.y" { OUTYY(("P(server_cache_min_ttl:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -5280,11 +5332,11 @@ yyreduce: else cfg_parser->cfg->min_ttl = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5284 "util/configparser.c" +#line 5336 "util/configparser.c" break; - case 505: /* server_bogus_ttl: VAR_BOGUS_TTL STRING_ARG */ -#line 2111 "util/configparser.y" + case 506: /* server_bogus_ttl: VAR_BOGUS_TTL STRING_ARG */ +#line 2118 "util/configparser.y" { OUTYY(("P(server_bogus_ttl:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -5292,11 +5344,11 @@ yyreduce: else cfg_parser->cfg->bogus_ttl = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5296 "util/configparser.c" +#line 5348 "util/configparser.c" break; - case 506: /* server_val_clean_additional: VAR_VAL_CLEAN_ADDITIONAL STRING_ARG */ -#line 2120 "util/configparser.y" + case 507: /* server_val_clean_additional: VAR_VAL_CLEAN_ADDITIONAL STRING_ARG */ +#line 2127 "util/configparser.y" { OUTYY(("P(server_val_clean_additional:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5305,11 +5357,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5309 "util/configparser.c" +#line 5361 "util/configparser.c" break; - case 507: /* server_val_permissive_mode: VAR_VAL_PERMISSIVE_MODE STRING_ARG */ -#line 2130 "util/configparser.y" + case 508: /* server_val_permissive_mode: VAR_VAL_PERMISSIVE_MODE STRING_ARG */ +#line 2137 "util/configparser.y" { OUTYY(("P(server_val_permissive_mode:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5318,11 +5370,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5322 "util/configparser.c" +#line 5374 "util/configparser.c" break; - case 508: /* server_aggressive_nsec: VAR_AGGRESSIVE_NSEC STRING_ARG */ -#line 2140 "util/configparser.y" + case 509: /* server_aggressive_nsec: VAR_AGGRESSIVE_NSEC STRING_ARG */ +#line 2147 "util/configparser.y" { OUTYY(("P(server_aggressive_nsec:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5332,11 +5384,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5336 "util/configparser.c" +#line 5388 "util/configparser.c" break; - case 509: /* server_ignore_cd_flag: VAR_IGNORE_CD_FLAG STRING_ARG */ -#line 2151 "util/configparser.y" + case 510: /* server_ignore_cd_flag: VAR_IGNORE_CD_FLAG STRING_ARG */ +#line 2158 "util/configparser.y" { OUTYY(("P(server_ignore_cd_flag:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5344,11 +5396,11 @@ yyreduce: else cfg_parser->cfg->ignore_cd = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5348 "util/configparser.c" +#line 5400 "util/configparser.c" break; - case 510: /* server_disable_edns_do: VAR_DISABLE_EDNS_DO STRING_ARG */ -#line 2160 "util/configparser.y" + case 511: /* server_disable_edns_do: VAR_DISABLE_EDNS_DO STRING_ARG */ +#line 2167 "util/configparser.y" { OUTYY(("P(server_disable_edns_do:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5356,11 +5408,11 @@ yyreduce: else cfg_parser->cfg->disable_edns_do = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5360 "util/configparser.c" +#line 5412 "util/configparser.c" break; - case 511: /* server_serve_expired: VAR_SERVE_EXPIRED STRING_ARG */ -#line 2169 "util/configparser.y" + case 512: /* server_serve_expired: VAR_SERVE_EXPIRED STRING_ARG */ +#line 2176 "util/configparser.y" { OUTYY(("P(server_serve_expired:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5368,11 +5420,11 @@ yyreduce: else cfg_parser->cfg->serve_expired = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5372 "util/configparser.c" +#line 5424 "util/configparser.c" break; - case 512: /* server_serve_expired_ttl: VAR_SERVE_EXPIRED_TTL STRING_ARG */ -#line 2178 "util/configparser.y" + case 513: /* server_serve_expired_ttl: VAR_SERVE_EXPIRED_TTL STRING_ARG */ +#line 2185 "util/configparser.y" { OUTYY(("P(server_serve_expired_ttl:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -5380,11 +5432,11 @@ yyreduce: else cfg_parser->cfg->serve_expired_ttl = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5384 "util/configparser.c" +#line 5436 "util/configparser.c" break; - case 513: /* server_serve_expired_ttl_reset: VAR_SERVE_EXPIRED_TTL_RESET STRING_ARG */ -#line 2187 "util/configparser.y" + case 514: /* server_serve_expired_ttl_reset: VAR_SERVE_EXPIRED_TTL_RESET STRING_ARG */ +#line 2194 "util/configparser.y" { OUTYY(("P(server_serve_expired_ttl_reset:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5392,11 +5444,11 @@ yyreduce: else cfg_parser->cfg->serve_expired_ttl_reset = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5396 "util/configparser.c" +#line 5448 "util/configparser.c" break; - case 514: /* server_serve_expired_reply_ttl: VAR_SERVE_EXPIRED_REPLY_TTL STRING_ARG */ -#line 2196 "util/configparser.y" + case 515: /* server_serve_expired_reply_ttl: VAR_SERVE_EXPIRED_REPLY_TTL STRING_ARG */ +#line 2203 "util/configparser.y" { OUTYY(("P(server_serve_expired_reply_ttl:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -5404,11 +5456,11 @@ yyreduce: else cfg_parser->cfg->serve_expired_reply_ttl = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5408 "util/configparser.c" +#line 5460 "util/configparser.c" break; - case 515: /* server_serve_expired_client_timeout: VAR_SERVE_EXPIRED_CLIENT_TIMEOUT STRING_ARG */ -#line 2205 "util/configparser.y" + case 516: /* server_serve_expired_client_timeout: VAR_SERVE_EXPIRED_CLIENT_TIMEOUT STRING_ARG */ +#line 2212 "util/configparser.y" { OUTYY(("P(server_serve_expired_client_timeout:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -5416,11 +5468,11 @@ yyreduce: else cfg_parser->cfg->serve_expired_client_timeout = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5420 "util/configparser.c" +#line 5472 "util/configparser.c" break; - case 516: /* server_ede_serve_expired: VAR_EDE_SERVE_EXPIRED STRING_ARG */ -#line 2214 "util/configparser.y" + case 517: /* server_ede_serve_expired: VAR_EDE_SERVE_EXPIRED STRING_ARG */ +#line 2221 "util/configparser.y" { OUTYY(("P(server_ede_serve_expired:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5428,11 +5480,11 @@ yyreduce: else cfg_parser->cfg->ede_serve_expired = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5432 "util/configparser.c" +#line 5484 "util/configparser.c" break; - case 517: /* server_serve_original_ttl: VAR_SERVE_ORIGINAL_TTL STRING_ARG */ -#line 2223 "util/configparser.y" + case 518: /* server_serve_original_ttl: VAR_SERVE_ORIGINAL_TTL STRING_ARG */ +#line 2230 "util/configparser.y" { OUTYY(("P(server_serve_original_ttl:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5440,11 +5492,11 @@ yyreduce: else cfg_parser->cfg->serve_original_ttl = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5444 "util/configparser.c" +#line 5496 "util/configparser.c" break; - case 518: /* server_fake_dsa: VAR_FAKE_DSA STRING_ARG */ -#line 2232 "util/configparser.y" + case 519: /* server_fake_dsa: VAR_FAKE_DSA STRING_ARG */ +#line 2239 "util/configparser.y" { OUTYY(("P(server_fake_dsa:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5456,11 +5508,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 5460 "util/configparser.c" +#line 5512 "util/configparser.c" break; - case 519: /* server_fake_sha1: VAR_FAKE_SHA1 STRING_ARG */ -#line 2245 "util/configparser.y" + case 520: /* server_fake_sha1: VAR_FAKE_SHA1 STRING_ARG */ +#line 2252 "util/configparser.y" { OUTYY(("P(server_fake_sha1:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5472,11 +5524,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 5476 "util/configparser.c" +#line 5528 "util/configparser.c" break; - case 520: /* server_val_log_level: VAR_VAL_LOG_LEVEL STRING_ARG */ -#line 2258 "util/configparser.y" + case 521: /* server_val_log_level: VAR_VAL_LOG_LEVEL STRING_ARG */ +#line 2265 "util/configparser.y" { OUTYY(("P(server_val_log_level:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -5484,21 +5536,21 @@ yyreduce: else cfg_parser->cfg->val_log_level = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5488 "util/configparser.c" +#line 5540 "util/configparser.c" break; - case 521: /* server_val_nsec3_keysize_iterations: VAR_VAL_NSEC3_KEYSIZE_ITERATIONS STRING_ARG */ -#line 2267 "util/configparser.y" + case 522: /* server_val_nsec3_keysize_iterations: VAR_VAL_NSEC3_KEYSIZE_ITERATIONS STRING_ARG */ +#line 2274 "util/configparser.y" { OUTYY(("P(server_val_nsec3_keysize_iterations:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->val_nsec3_key_iterations); cfg_parser->cfg->val_nsec3_key_iterations = (yyvsp[0].str); } -#line 5498 "util/configparser.c" +#line 5550 "util/configparser.c" break; - case 522: /* server_zonemd_permissive_mode: VAR_ZONEMD_PERMISSIVE_MODE STRING_ARG */ -#line 2274 "util/configparser.y" + case 523: /* server_zonemd_permissive_mode: VAR_ZONEMD_PERMISSIVE_MODE STRING_ARG */ +#line 2281 "util/configparser.y" { OUTYY(("P(server_zonemd_permissive_mode:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5506,11 +5558,11 @@ yyreduce: else cfg_parser->cfg->zonemd_permissive_mode = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5510 "util/configparser.c" +#line 5562 "util/configparser.c" break; - case 523: /* server_add_holddown: VAR_ADD_HOLDDOWN STRING_ARG */ -#line 2283 "util/configparser.y" + case 524: /* server_add_holddown: VAR_ADD_HOLDDOWN STRING_ARG */ +#line 2290 "util/configparser.y" { OUTYY(("P(server_add_holddown:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -5518,11 +5570,11 @@ yyreduce: else cfg_parser->cfg->add_holddown = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5522 "util/configparser.c" +#line 5574 "util/configparser.c" break; - case 524: /* server_del_holddown: VAR_DEL_HOLDDOWN STRING_ARG */ -#line 2292 "util/configparser.y" + case 525: /* server_del_holddown: VAR_DEL_HOLDDOWN STRING_ARG */ +#line 2299 "util/configparser.y" { OUTYY(("P(server_del_holddown:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -5530,11 +5582,11 @@ yyreduce: else cfg_parser->cfg->del_holddown = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5534 "util/configparser.c" +#line 5586 "util/configparser.c" break; - case 525: /* server_keep_missing: VAR_KEEP_MISSING STRING_ARG */ -#line 2301 "util/configparser.y" + case 526: /* server_keep_missing: VAR_KEEP_MISSING STRING_ARG */ +#line 2308 "util/configparser.y" { OUTYY(("P(server_keep_missing:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -5542,11 +5594,11 @@ yyreduce: else cfg_parser->cfg->keep_missing = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5546 "util/configparser.c" +#line 5598 "util/configparser.c" break; - case 526: /* server_permit_small_holddown: VAR_PERMIT_SMALL_HOLDDOWN STRING_ARG */ -#line 2310 "util/configparser.y" + case 527: /* server_permit_small_holddown: VAR_PERMIT_SMALL_HOLDDOWN STRING_ARG */ +#line 2317 "util/configparser.y" { OUTYY(("P(server_permit_small_holddown:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5555,22 +5607,22 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5559 "util/configparser.c" +#line 5611 "util/configparser.c" break; - case 527: /* server_key_cache_size: VAR_KEY_CACHE_SIZE STRING_ARG */ -#line 2320 "util/configparser.y" + case 528: /* server_key_cache_size: VAR_KEY_CACHE_SIZE STRING_ARG */ +#line 2327 "util/configparser.y" { OUTYY(("P(server_key_cache_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->key_cache_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 5570 "util/configparser.c" +#line 5622 "util/configparser.c" break; - case 528: /* server_key_cache_slabs: VAR_KEY_CACHE_SLABS STRING_ARG */ -#line 2328 "util/configparser.y" + case 529: /* server_key_cache_slabs: VAR_KEY_CACHE_SLABS STRING_ARG */ +#line 2335 "util/configparser.y" { OUTYY(("P(server_key_cache_slabs:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) { @@ -5582,22 +5634,22 @@ yyreduce: } free((yyvsp[0].str)); } -#line 5586 "util/configparser.c" +#line 5638 "util/configparser.c" break; - case 529: /* server_neg_cache_size: VAR_NEG_CACHE_SIZE STRING_ARG */ -#line 2341 "util/configparser.y" + case 530: /* server_neg_cache_size: VAR_NEG_CACHE_SIZE STRING_ARG */ +#line 2348 "util/configparser.y" { OUTYY(("P(server_neg_cache_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->neg_cache_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 5597 "util/configparser.c" +#line 5649 "util/configparser.c" break; - case 530: /* server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG */ -#line 2349 "util/configparser.y" + case 531: /* server_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG */ +#line 2356 "util/configparser.y" { OUTYY(("P(server_local_zone:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "static")!=0 && strcmp((yyvsp[0].str), "deny")!=0 && @@ -5652,21 +5704,21 @@ yyreduce: fatal_exit("out of memory adding local-zone"); } } -#line 5656 "util/configparser.c" +#line 5708 "util/configparser.c" break; - case 531: /* server_local_data: VAR_LOCAL_DATA STRING_ARG */ -#line 2405 "util/configparser.y" + case 532: /* server_local_data: VAR_LOCAL_DATA STRING_ARG */ +#line 2412 "util/configparser.y" { OUTYY(("P(server_local_data:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->local_data, (yyvsp[0].str))) fatal_exit("out of memory adding local-data"); } -#line 5666 "util/configparser.c" +#line 5718 "util/configparser.c" break; - case 532: /* server_local_data_ptr: VAR_LOCAL_DATA_PTR STRING_ARG */ -#line 2412 "util/configparser.y" + case 533: /* server_local_data_ptr: VAR_LOCAL_DATA_PTR STRING_ARG */ +#line 2419 "util/configparser.y" { char* ptr; OUTYY(("P(server_local_data_ptr:%s)\n", (yyvsp[0].str))); @@ -5680,11 +5732,11 @@ yyreduce: yyerror("local-data-ptr could not be reversed"); } } -#line 5684 "util/configparser.c" +#line 5736 "util/configparser.c" break; - case 533: /* server_minimal_responses: VAR_MINIMAL_RESPONSES STRING_ARG */ -#line 2427 "util/configparser.y" + case 534: /* server_minimal_responses: VAR_MINIMAL_RESPONSES STRING_ARG */ +#line 2434 "util/configparser.y" { OUTYY(("P(server_minimal_responses:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5693,11 +5745,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5697 "util/configparser.c" +#line 5749 "util/configparser.c" break; - case 534: /* server_rrset_roundrobin: VAR_RRSET_ROUNDROBIN STRING_ARG */ -#line 2437 "util/configparser.y" + case 535: /* server_rrset_roundrobin: VAR_RRSET_ROUNDROBIN STRING_ARG */ +#line 2444 "util/configparser.y" { OUTYY(("P(server_rrset_roundrobin:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5706,51 +5758,51 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5710 "util/configparser.c" +#line 5762 "util/configparser.c" break; - case 535: /* server_unknown_server_time_limit: VAR_UNKNOWN_SERVER_TIME_LIMIT STRING_ARG */ -#line 2447 "util/configparser.y" + case 536: /* server_unknown_server_time_limit: VAR_UNKNOWN_SERVER_TIME_LIMIT STRING_ARG */ +#line 2454 "util/configparser.y" { OUTYY(("P(server_unknown_server_time_limit:%s)\n", (yyvsp[0].str))); cfg_parser->cfg->unknown_server_time_limit = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5720 "util/configparser.c" +#line 5772 "util/configparser.c" break; - case 536: /* server_discard_timeout: VAR_DISCARD_TIMEOUT STRING_ARG */ -#line 2454 "util/configparser.y" + case 537: /* server_discard_timeout: VAR_DISCARD_TIMEOUT STRING_ARG */ +#line 2461 "util/configparser.y" { OUTYY(("P(server_discard_timeout:%s)\n", (yyvsp[0].str))); cfg_parser->cfg->discard_timeout = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5730 "util/configparser.c" +#line 5782 "util/configparser.c" break; - case 537: /* server_wait_limit: VAR_WAIT_LIMIT STRING_ARG */ -#line 2461 "util/configparser.y" + case 538: /* server_wait_limit: VAR_WAIT_LIMIT STRING_ARG */ +#line 2468 "util/configparser.y" { OUTYY(("P(server_wait_limit:%s)\n", (yyvsp[0].str))); cfg_parser->cfg->wait_limit = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5740 "util/configparser.c" +#line 5792 "util/configparser.c" break; - case 538: /* server_wait_limit_cookie: VAR_WAIT_LIMIT_COOKIE STRING_ARG */ -#line 2468 "util/configparser.y" + case 539: /* server_wait_limit_cookie: VAR_WAIT_LIMIT_COOKIE STRING_ARG */ +#line 2475 "util/configparser.y" { OUTYY(("P(server_wait_limit_cookie:%s)\n", (yyvsp[0].str))); cfg_parser->cfg->wait_limit_cookie = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5750 "util/configparser.c" +#line 5802 "util/configparser.c" break; - case 539: /* server_wait_limit_netblock: VAR_WAIT_LIMIT_NETBLOCK STRING_ARG STRING_ARG */ -#line 2475 "util/configparser.y" + case 540: /* server_wait_limit_netblock: VAR_WAIT_LIMIT_NETBLOCK STRING_ARG STRING_ARG */ +#line 2482 "util/configparser.y" { OUTYY(("P(server_wait_limit_netblock:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) { @@ -5764,11 +5816,11 @@ yyreduce: "wait-limit-netblock"); } } -#line 5768 "util/configparser.c" +#line 5820 "util/configparser.c" break; - case 540: /* server_wait_limit_cookie_netblock: VAR_WAIT_LIMIT_COOKIE_NETBLOCK STRING_ARG STRING_ARG */ -#line 2490 "util/configparser.y" + case 541: /* server_wait_limit_cookie_netblock: VAR_WAIT_LIMIT_COOKIE_NETBLOCK STRING_ARG STRING_ARG */ +#line 2497 "util/configparser.y" { OUTYY(("P(server_wait_limit_cookie_netblock:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) { @@ -5782,31 +5834,31 @@ yyreduce: "wait-limit-cookie-netblock"); } } -#line 5786 "util/configparser.c" +#line 5838 "util/configparser.c" break; - case 541: /* server_max_udp_size: VAR_MAX_UDP_SIZE STRING_ARG */ -#line 2505 "util/configparser.y" + case 542: /* server_max_udp_size: VAR_MAX_UDP_SIZE STRING_ARG */ +#line 2512 "util/configparser.y" { OUTYY(("P(server_max_udp_size:%s)\n", (yyvsp[0].str))); cfg_parser->cfg->max_udp_size = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 5796 "util/configparser.c" +#line 5848 "util/configparser.c" break; - case 542: /* server_dns64_prefix: VAR_DNS64_PREFIX STRING_ARG */ -#line 2512 "util/configparser.y" + case 543: /* server_dns64_prefix: VAR_DNS64_PREFIX STRING_ARG */ +#line 2519 "util/configparser.y" { OUTYY(("P(dns64_prefix:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dns64_prefix); cfg_parser->cfg->dns64_prefix = (yyvsp[0].str); } -#line 5806 "util/configparser.c" +#line 5858 "util/configparser.c" break; - case 543: /* server_dns64_synthall: VAR_DNS64_SYNTHALL STRING_ARG */ -#line 2519 "util/configparser.y" + case 544: /* server_dns64_synthall: VAR_DNS64_SYNTHALL STRING_ARG */ +#line 2526 "util/configparser.y" { OUTYY(("P(server_dns64_synthall:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -5814,32 +5866,32 @@ yyreduce: else cfg_parser->cfg->dns64_synthall = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 5818 "util/configparser.c" +#line 5870 "util/configparser.c" break; - case 544: /* server_dns64_ignore_aaaa: VAR_DNS64_IGNORE_AAAA STRING_ARG */ -#line 2528 "util/configparser.y" + case 545: /* server_dns64_ignore_aaaa: VAR_DNS64_IGNORE_AAAA STRING_ARG */ +#line 2535 "util/configparser.y" { OUTYY(("P(dns64_ignore_aaaa:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->dns64_ignore_aaaa, (yyvsp[0].str))) fatal_exit("out of memory adding dns64-ignore-aaaa"); } -#line 5829 "util/configparser.c" +#line 5881 "util/configparser.c" break; - case 545: /* server_nat64_prefix: VAR_NAT64_PREFIX STRING_ARG */ -#line 2536 "util/configparser.y" + case 546: /* server_nat64_prefix: VAR_NAT64_PREFIX STRING_ARG */ +#line 2543 "util/configparser.y" { OUTYY(("P(nat64_prefix:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->nat64_prefix); cfg_parser->cfg->nat64_prefix = (yyvsp[0].str); } -#line 5839 "util/configparser.c" +#line 5891 "util/configparser.c" break; - case 546: /* server_define_tag: VAR_DEFINE_TAG STRING_ARG */ -#line 2543 "util/configparser.y" + case 547: /* server_define_tag: VAR_DEFINE_TAG STRING_ARG */ +#line 2550 "util/configparser.y" { char* p, *s = (yyvsp[0].str); OUTYY(("P(server_define_tag:%s)\n", (yyvsp[0].str))); @@ -5852,11 +5904,11 @@ yyreduce: } free((yyvsp[0].str)); } -#line 5856 "util/configparser.c" +#line 5908 "util/configparser.c" break; - case 547: /* server_local_zone_tag: VAR_LOCAL_ZONE_TAG STRING_ARG STRING_ARG */ -#line 2557 "util/configparser.y" + case 548: /* server_local_zone_tag: VAR_LOCAL_ZONE_TAG STRING_ARG STRING_ARG */ +#line 2564 "util/configparser.y" { size_t len = 0; uint8_t* bitlist = config_parse_taglist(cfg_parser->cfg, (yyvsp[0].str), @@ -5876,11 +5928,11 @@ yyreduce: } } } -#line 5880 "util/configparser.c" +#line 5932 "util/configparser.c" break; - case 548: /* server_access_control_tag: VAR_ACCESS_CONTROL_TAG STRING_ARG STRING_ARG */ -#line 2578 "util/configparser.y" + case 549: /* server_access_control_tag: VAR_ACCESS_CONTROL_TAG STRING_ARG STRING_ARG */ +#line 2585 "util/configparser.y" { size_t len = 0; uint8_t* bitlist = config_parse_taglist(cfg_parser->cfg, (yyvsp[0].str), @@ -5900,11 +5952,11 @@ yyreduce: } } } -#line 5904 "util/configparser.c" +#line 5956 "util/configparser.c" break; - case 549: /* server_access_control_tag_action: VAR_ACCESS_CONTROL_TAG_ACTION STRING_ARG STRING_ARG STRING_ARG */ -#line 2599 "util/configparser.y" + case 550: /* server_access_control_tag_action: VAR_ACCESS_CONTROL_TAG_ACTION STRING_ARG STRING_ARG STRING_ARG */ +#line 2606 "util/configparser.y" { OUTYY(("P(server_access_control_tag_action:%s %s %s)\n", (yyvsp[-2].str), (yyvsp[-1].str), (yyvsp[0].str))); if(!cfg_str3list_insert(&cfg_parser->cfg->acl_tag_actions, @@ -5915,11 +5967,11 @@ yyreduce: free((yyvsp[0].str)); } } -#line 5919 "util/configparser.c" +#line 5971 "util/configparser.c" break; - case 550: /* server_access_control_tag_data: VAR_ACCESS_CONTROL_TAG_DATA STRING_ARG STRING_ARG STRING_ARG */ -#line 2611 "util/configparser.y" + case 551: /* server_access_control_tag_data: VAR_ACCESS_CONTROL_TAG_DATA STRING_ARG STRING_ARG STRING_ARG */ +#line 2618 "util/configparser.y" { OUTYY(("P(server_access_control_tag_data:%s %s %s)\n", (yyvsp[-2].str), (yyvsp[-1].str), (yyvsp[0].str))); if(!cfg_str3list_insert(&cfg_parser->cfg->acl_tag_datas, @@ -5930,11 +5982,11 @@ yyreduce: free((yyvsp[0].str)); } } -#line 5934 "util/configparser.c" +#line 5986 "util/configparser.c" break; - case 551: /* server_local_zone_override: VAR_LOCAL_ZONE_OVERRIDE STRING_ARG STRING_ARG STRING_ARG */ -#line 2623 "util/configparser.y" + case 552: /* server_local_zone_override: VAR_LOCAL_ZONE_OVERRIDE STRING_ARG STRING_ARG STRING_ARG */ +#line 2630 "util/configparser.y" { OUTYY(("P(server_local_zone_override:%s %s %s)\n", (yyvsp[-2].str), (yyvsp[-1].str), (yyvsp[0].str))); if(!cfg_str3list_insert(&cfg_parser->cfg->local_zone_overrides, @@ -5945,11 +5997,11 @@ yyreduce: free((yyvsp[0].str)); } } -#line 5949 "util/configparser.c" +#line 6001 "util/configparser.c" break; - case 552: /* server_access_control_view: VAR_ACCESS_CONTROL_VIEW STRING_ARG STRING_ARG */ -#line 2635 "util/configparser.y" + case 553: /* server_access_control_view: VAR_ACCESS_CONTROL_VIEW STRING_ARG STRING_ARG */ +#line 2642 "util/configparser.y" { OUTYY(("P(server_access_control_view:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); if(!cfg_str2list_insert(&cfg_parser->cfg->acl_view, @@ -5957,11 +6009,11 @@ yyreduce: yyerror("out of memory"); } } -#line 5961 "util/configparser.c" +#line 6013 "util/configparser.c" break; - case 553: /* server_interface_tag: VAR_INTERFACE_TAG STRING_ARG STRING_ARG */ -#line 2644 "util/configparser.y" + case 554: /* server_interface_tag: VAR_INTERFACE_TAG STRING_ARG STRING_ARG */ +#line 2651 "util/configparser.y" { size_t len = 0; uint8_t* bitlist = config_parse_taglist(cfg_parser->cfg, (yyvsp[0].str), @@ -5981,11 +6033,11 @@ yyreduce: } } } -#line 5985 "util/configparser.c" +#line 6037 "util/configparser.c" break; - case 554: /* server_interface_tag_action: VAR_INTERFACE_TAG_ACTION STRING_ARG STRING_ARG STRING_ARG */ -#line 2665 "util/configparser.y" + case 555: /* server_interface_tag_action: VAR_INTERFACE_TAG_ACTION STRING_ARG STRING_ARG STRING_ARG */ +#line 2672 "util/configparser.y" { OUTYY(("P(server_interface_tag_action:%s %s %s)\n", (yyvsp[-2].str), (yyvsp[-1].str), (yyvsp[0].str))); if(!cfg_str3list_insert(&cfg_parser->cfg->interface_tag_actions, @@ -5996,11 +6048,11 @@ yyreduce: free((yyvsp[0].str)); } } -#line 6000 "util/configparser.c" +#line 6052 "util/configparser.c" break; - case 555: /* server_interface_tag_data: VAR_INTERFACE_TAG_DATA STRING_ARG STRING_ARG STRING_ARG */ -#line 2677 "util/configparser.y" + case 556: /* server_interface_tag_data: VAR_INTERFACE_TAG_DATA STRING_ARG STRING_ARG STRING_ARG */ +#line 2684 "util/configparser.y" { OUTYY(("P(server_interface_tag_data:%s %s %s)\n", (yyvsp[-2].str), (yyvsp[-1].str), (yyvsp[0].str))); if(!cfg_str3list_insert(&cfg_parser->cfg->interface_tag_datas, @@ -6011,11 +6063,11 @@ yyreduce: free((yyvsp[0].str)); } } -#line 6015 "util/configparser.c" +#line 6067 "util/configparser.c" break; - case 556: /* server_interface_view: VAR_INTERFACE_VIEW STRING_ARG STRING_ARG */ -#line 2689 "util/configparser.y" + case 557: /* server_interface_view: VAR_INTERFACE_VIEW STRING_ARG STRING_ARG */ +#line 2696 "util/configparser.y" { OUTYY(("P(server_interface_view:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); if(!cfg_str2list_insert(&cfg_parser->cfg->interface_view, @@ -6023,11 +6075,11 @@ yyreduce: yyerror("out of memory"); } } -#line 6027 "util/configparser.c" +#line 6079 "util/configparser.c" break; - case 557: /* server_response_ip_tag: VAR_RESPONSE_IP_TAG STRING_ARG STRING_ARG */ -#line 2698 "util/configparser.y" + case 558: /* server_response_ip_tag: VAR_RESPONSE_IP_TAG STRING_ARG STRING_ARG */ +#line 2705 "util/configparser.y" { size_t len = 0; uint8_t* bitlist = config_parse_taglist(cfg_parser->cfg, (yyvsp[0].str), @@ -6047,11 +6099,11 @@ yyreduce: } } } -#line 6051 "util/configparser.c" +#line 6103 "util/configparser.c" break; - case 558: /* server_ip_ratelimit: VAR_IP_RATELIMIT STRING_ARG */ -#line 2719 "util/configparser.y" + case 559: /* server_ip_ratelimit: VAR_IP_RATELIMIT STRING_ARG */ +#line 2726 "util/configparser.y" { OUTYY(("P(server_ip_ratelimit:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -6059,11 +6111,11 @@ yyreduce: else cfg_parser->cfg->ip_ratelimit = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 6063 "util/configparser.c" +#line 6115 "util/configparser.c" break; - case 559: /* server_ip_ratelimit_cookie: VAR_IP_RATELIMIT_COOKIE STRING_ARG */ -#line 2728 "util/configparser.y" + case 560: /* server_ip_ratelimit_cookie: VAR_IP_RATELIMIT_COOKIE STRING_ARG */ +#line 2735 "util/configparser.y" { OUTYY(("P(server_ip_ratelimit_cookie:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -6071,11 +6123,11 @@ yyreduce: else cfg_parser->cfg->ip_ratelimit_cookie = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 6075 "util/configparser.c" +#line 6127 "util/configparser.c" break; - case 560: /* server_ratelimit: VAR_RATELIMIT STRING_ARG */ -#line 2737 "util/configparser.y" + case 561: /* server_ratelimit: VAR_RATELIMIT STRING_ARG */ +#line 2744 "util/configparser.y" { OUTYY(("P(server_ratelimit:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -6083,33 +6135,33 @@ yyreduce: else cfg_parser->cfg->ratelimit = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 6087 "util/configparser.c" +#line 6139 "util/configparser.c" break; - case 561: /* server_ip_ratelimit_size: VAR_IP_RATELIMIT_SIZE STRING_ARG */ -#line 2746 "util/configparser.y" + case 562: /* server_ip_ratelimit_size: VAR_IP_RATELIMIT_SIZE STRING_ARG */ +#line 2753 "util/configparser.y" { OUTYY(("P(server_ip_ratelimit_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->ip_ratelimit_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 6098 "util/configparser.c" +#line 6150 "util/configparser.c" break; - case 562: /* server_ratelimit_size: VAR_RATELIMIT_SIZE STRING_ARG */ -#line 2754 "util/configparser.y" + case 563: /* server_ratelimit_size: VAR_RATELIMIT_SIZE STRING_ARG */ +#line 2761 "util/configparser.y" { OUTYY(("P(server_ratelimit_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->ratelimit_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 6109 "util/configparser.c" +#line 6161 "util/configparser.c" break; - case 563: /* server_ip_ratelimit_slabs: VAR_IP_RATELIMIT_SLABS STRING_ARG */ -#line 2762 "util/configparser.y" + case 564: /* server_ip_ratelimit_slabs: VAR_IP_RATELIMIT_SLABS STRING_ARG */ +#line 2769 "util/configparser.y" { OUTYY(("P(server_ip_ratelimit_slabs:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) { @@ -6121,11 +6173,11 @@ yyreduce: } free((yyvsp[0].str)); } -#line 6125 "util/configparser.c" +#line 6177 "util/configparser.c" break; - case 564: /* server_ratelimit_slabs: VAR_RATELIMIT_SLABS STRING_ARG */ -#line 2775 "util/configparser.y" + case 565: /* server_ratelimit_slabs: VAR_RATELIMIT_SLABS STRING_ARG */ +#line 2782 "util/configparser.y" { OUTYY(("P(server_ratelimit_slabs:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) { @@ -6137,11 +6189,11 @@ yyreduce: } free((yyvsp[0].str)); } -#line 6141 "util/configparser.c" +#line 6193 "util/configparser.c" break; - case 565: /* server_ratelimit_for_domain: VAR_RATELIMIT_FOR_DOMAIN STRING_ARG STRING_ARG */ -#line 2788 "util/configparser.y" + case 566: /* server_ratelimit_for_domain: VAR_RATELIMIT_FOR_DOMAIN STRING_ARG STRING_ARG */ +#line 2795 "util/configparser.y" { OUTYY(("P(server_ratelimit_for_domain:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) { @@ -6155,11 +6207,11 @@ yyreduce: "ratelimit-for-domain"); } } -#line 6159 "util/configparser.c" +#line 6211 "util/configparser.c" break; - case 566: /* server_ratelimit_below_domain: VAR_RATELIMIT_BELOW_DOMAIN STRING_ARG STRING_ARG */ -#line 2803 "util/configparser.y" + case 567: /* server_ratelimit_below_domain: VAR_RATELIMIT_BELOW_DOMAIN STRING_ARG STRING_ARG */ +#line 2810 "util/configparser.y" { OUTYY(("P(server_ratelimit_below_domain:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) { @@ -6173,11 +6225,11 @@ yyreduce: "ratelimit-below-domain"); } } -#line 6177 "util/configparser.c" +#line 6229 "util/configparser.c" break; - case 567: /* server_ip_ratelimit_factor: VAR_IP_RATELIMIT_FACTOR STRING_ARG */ -#line 2818 "util/configparser.y" + case 568: /* server_ip_ratelimit_factor: VAR_IP_RATELIMIT_FACTOR STRING_ARG */ +#line 2825 "util/configparser.y" { OUTYY(("P(server_ip_ratelimit_factor:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -6185,11 +6237,11 @@ yyreduce: else cfg_parser->cfg->ip_ratelimit_factor = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 6189 "util/configparser.c" +#line 6241 "util/configparser.c" break; - case 568: /* server_ratelimit_factor: VAR_RATELIMIT_FACTOR STRING_ARG */ -#line 2827 "util/configparser.y" + case 569: /* server_ratelimit_factor: VAR_RATELIMIT_FACTOR STRING_ARG */ +#line 2834 "util/configparser.y" { OUTYY(("P(server_ratelimit_factor:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -6197,11 +6249,11 @@ yyreduce: else cfg_parser->cfg->ratelimit_factor = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 6201 "util/configparser.c" +#line 6253 "util/configparser.c" break; - case 569: /* server_ip_ratelimit_backoff: VAR_IP_RATELIMIT_BACKOFF STRING_ARG */ -#line 2836 "util/configparser.y" + case 570: /* server_ip_ratelimit_backoff: VAR_IP_RATELIMIT_BACKOFF STRING_ARG */ +#line 2843 "util/configparser.y" { OUTYY(("P(server_ip_ratelimit_backoff:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6210,11 +6262,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6214 "util/configparser.c" +#line 6266 "util/configparser.c" break; - case 570: /* server_ratelimit_backoff: VAR_RATELIMIT_BACKOFF STRING_ARG */ -#line 2846 "util/configparser.y" + case 571: /* server_ratelimit_backoff: VAR_RATELIMIT_BACKOFF STRING_ARG */ +#line 2853 "util/configparser.y" { OUTYY(("P(server_ratelimit_backoff:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6223,11 +6275,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6227 "util/configparser.c" +#line 6279 "util/configparser.c" break; - case 571: /* server_outbound_msg_retry: VAR_OUTBOUND_MSG_RETRY STRING_ARG */ -#line 2856 "util/configparser.y" + case 572: /* server_outbound_msg_retry: VAR_OUTBOUND_MSG_RETRY STRING_ARG */ +#line 2863 "util/configparser.y" { OUTYY(("P(server_outbound_msg_retry:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -6235,11 +6287,11 @@ yyreduce: else cfg_parser->cfg->outbound_msg_retry = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 6239 "util/configparser.c" +#line 6291 "util/configparser.c" break; - case 572: /* server_max_sent_count: VAR_MAX_SENT_COUNT STRING_ARG */ -#line 2865 "util/configparser.y" + case 573: /* server_max_sent_count: VAR_MAX_SENT_COUNT STRING_ARG */ +#line 2872 "util/configparser.y" { OUTYY(("P(server_max_sent_count:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -6247,11 +6299,11 @@ yyreduce: else cfg_parser->cfg->max_sent_count = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 6251 "util/configparser.c" +#line 6303 "util/configparser.c" break; - case 573: /* server_max_query_restarts: VAR_MAX_QUERY_RESTARTS STRING_ARG */ -#line 2874 "util/configparser.y" + case 574: /* server_max_query_restarts: VAR_MAX_QUERY_RESTARTS STRING_ARG */ +#line 2881 "util/configparser.y" { OUTYY(("P(server_max_query_restarts:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -6259,20 +6311,20 @@ yyreduce: else cfg_parser->cfg->max_query_restarts = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 6263 "util/configparser.c" +#line 6315 "util/configparser.c" break; - case 574: /* server_low_rtt: VAR_LOW_RTT STRING_ARG */ -#line 2883 "util/configparser.y" + case 575: /* server_low_rtt: VAR_LOW_RTT STRING_ARG */ +#line 2890 "util/configparser.y" { OUTYY(("P(low-rtt option is deprecated, use fast-server-num instead)\n")); free((yyvsp[0].str)); } -#line 6272 "util/configparser.c" +#line 6324 "util/configparser.c" break; - case 575: /* server_fast_server_num: VAR_FAST_SERVER_NUM STRING_ARG */ -#line 2889 "util/configparser.y" + case 576: /* server_fast_server_num: VAR_FAST_SERVER_NUM STRING_ARG */ +#line 2896 "util/configparser.y" { OUTYY(("P(server_fast_server_num:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) <= 0) @@ -6280,11 +6332,11 @@ yyreduce: else cfg_parser->cfg->fast_server_num = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 6284 "util/configparser.c" +#line 6336 "util/configparser.c" break; - case 576: /* server_fast_server_permil: VAR_FAST_SERVER_PERMIL STRING_ARG */ -#line 2898 "util/configparser.y" + case 577: /* server_fast_server_permil: VAR_FAST_SERVER_PERMIL STRING_ARG */ +#line 2905 "util/configparser.y" { OUTYY(("P(server_fast_server_permil:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -6292,11 +6344,11 @@ yyreduce: else cfg_parser->cfg->fast_server_permil = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 6296 "util/configparser.c" +#line 6348 "util/configparser.c" break; - case 577: /* server_qname_minimisation: VAR_QNAME_MINIMISATION STRING_ARG */ -#line 2907 "util/configparser.y" + case 578: /* server_qname_minimisation: VAR_QNAME_MINIMISATION STRING_ARG */ +#line 2914 "util/configparser.y" { OUTYY(("P(server_qname_minimisation:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6305,11 +6357,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6309 "util/configparser.c" +#line 6361 "util/configparser.c" break; - case 578: /* server_qname_minimisation_strict: VAR_QNAME_MINIMISATION_STRICT STRING_ARG */ -#line 2917 "util/configparser.y" + case 579: /* server_qname_minimisation_strict: VAR_QNAME_MINIMISATION_STRICT STRING_ARG */ +#line 2924 "util/configparser.y" { OUTYY(("P(server_qname_minimisation_strict:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6318,11 +6370,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6322 "util/configparser.c" +#line 6374 "util/configparser.c" break; - case 579: /* server_pad_responses: VAR_PAD_RESPONSES STRING_ARG */ -#line 2927 "util/configparser.y" + case 580: /* server_pad_responses: VAR_PAD_RESPONSES STRING_ARG */ +#line 2934 "util/configparser.y" { OUTYY(("P(server_pad_responses:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6331,11 +6383,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6335 "util/configparser.c" +#line 6387 "util/configparser.c" break; - case 580: /* server_pad_responses_block_size: VAR_PAD_RESPONSES_BLOCK_SIZE STRING_ARG */ -#line 2937 "util/configparser.y" + case 581: /* server_pad_responses_block_size: VAR_PAD_RESPONSES_BLOCK_SIZE STRING_ARG */ +#line 2944 "util/configparser.y" { OUTYY(("P(server_pad_responses_block_size:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -6343,11 +6395,11 @@ yyreduce: else cfg_parser->cfg->pad_responses_block_size = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 6347 "util/configparser.c" +#line 6399 "util/configparser.c" break; - case 581: /* server_pad_queries: VAR_PAD_QUERIES STRING_ARG */ -#line 2946 "util/configparser.y" + case 582: /* server_pad_queries: VAR_PAD_QUERIES STRING_ARG */ +#line 2953 "util/configparser.y" { OUTYY(("P(server_pad_queries:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6356,11 +6408,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6360 "util/configparser.c" +#line 6412 "util/configparser.c" break; - case 582: /* server_pad_queries_block_size: VAR_PAD_QUERIES_BLOCK_SIZE STRING_ARG */ -#line 2956 "util/configparser.y" + case 583: /* server_pad_queries_block_size: VAR_PAD_QUERIES_BLOCK_SIZE STRING_ARG */ +#line 2963 "util/configparser.y" { OUTYY(("P(server_pad_queries_block_size:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -6368,11 +6420,11 @@ yyreduce: else cfg_parser->cfg->pad_queries_block_size = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 6372 "util/configparser.c" +#line 6424 "util/configparser.c" break; - case 583: /* server_ipsecmod_enabled: VAR_IPSECMOD_ENABLED STRING_ARG */ -#line 2965 "util/configparser.y" + case 584: /* server_ipsecmod_enabled: VAR_IPSECMOD_ENABLED STRING_ARG */ +#line 2972 "util/configparser.y" { #ifdef USE_IPSECMOD OUTYY(("P(server_ipsecmod_enabled:%s)\n", (yyvsp[0].str))); @@ -6384,11 +6436,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 6388 "util/configparser.c" +#line 6440 "util/configparser.c" break; - case 584: /* server_ipsecmod_ignore_bogus: VAR_IPSECMOD_IGNORE_BOGUS STRING_ARG */ -#line 2978 "util/configparser.y" + case 585: /* server_ipsecmod_ignore_bogus: VAR_IPSECMOD_IGNORE_BOGUS STRING_ARG */ +#line 2985 "util/configparser.y" { #ifdef USE_IPSECMOD OUTYY(("P(server_ipsecmod_ignore_bogus:%s)\n", (yyvsp[0].str))); @@ -6400,11 +6452,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 6404 "util/configparser.c" +#line 6456 "util/configparser.c" break; - case 585: /* server_ipsecmod_hook: VAR_IPSECMOD_HOOK STRING_ARG */ -#line 2991 "util/configparser.y" + case 586: /* server_ipsecmod_hook: VAR_IPSECMOD_HOOK STRING_ARG */ +#line 2998 "util/configparser.y" { #ifdef USE_IPSECMOD OUTYY(("P(server_ipsecmod_hook:%s)\n", (yyvsp[0].str))); @@ -6415,11 +6467,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 6419 "util/configparser.c" +#line 6471 "util/configparser.c" break; - case 586: /* server_ipsecmod_max_ttl: VAR_IPSECMOD_MAX_TTL STRING_ARG */ -#line 3003 "util/configparser.y" + case 587: /* server_ipsecmod_max_ttl: VAR_IPSECMOD_MAX_TTL STRING_ARG */ +#line 3010 "util/configparser.y" { #ifdef USE_IPSECMOD OUTYY(("P(server_ipsecmod_max_ttl:%s)\n", (yyvsp[0].str))); @@ -6432,11 +6484,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 6436 "util/configparser.c" +#line 6488 "util/configparser.c" break; - case 587: /* server_ipsecmod_whitelist: VAR_IPSECMOD_WHITELIST STRING_ARG */ -#line 3017 "util/configparser.y" + case 588: /* server_ipsecmod_whitelist: VAR_IPSECMOD_WHITELIST STRING_ARG */ +#line 3024 "util/configparser.y" { #ifdef USE_IPSECMOD OUTYY(("P(server_ipsecmod_whitelist:%s)\n", (yyvsp[0].str))); @@ -6447,11 +6499,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 6451 "util/configparser.c" +#line 6503 "util/configparser.c" break; - case 588: /* server_ipsecmod_strict: VAR_IPSECMOD_STRICT STRING_ARG */ -#line 3029 "util/configparser.y" + case 589: /* server_ipsecmod_strict: VAR_IPSECMOD_STRICT STRING_ARG */ +#line 3036 "util/configparser.y" { #ifdef USE_IPSECMOD OUTYY(("P(server_ipsecmod_strict:%s)\n", (yyvsp[0].str))); @@ -6464,11 +6516,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 6468 "util/configparser.c" +#line 6520 "util/configparser.c" break; - case 589: /* server_edns_client_string: VAR_EDNS_CLIENT_STRING STRING_ARG STRING_ARG */ -#line 3043 "util/configparser.y" + case 590: /* server_edns_client_string: VAR_EDNS_CLIENT_STRING STRING_ARG STRING_ARG */ +#line 3050 "util/configparser.y" { OUTYY(("P(server_edns_client_string:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); if(!cfg_str2list_insert( @@ -6476,11 +6528,11 @@ yyreduce: fatal_exit("out of memory adding " "edns-client-string"); } -#line 6480 "util/configparser.c" +#line 6532 "util/configparser.c" break; - case 590: /* server_edns_client_string_opcode: VAR_EDNS_CLIENT_STRING_OPCODE STRING_ARG */ -#line 3052 "util/configparser.y" + case 591: /* server_edns_client_string_opcode: VAR_EDNS_CLIENT_STRING_OPCODE STRING_ARG */ +#line 3059 "util/configparser.y" { OUTYY(("P(edns_client_string_opcode:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -6490,11 +6542,11 @@ yyreduce: else cfg_parser->cfg->edns_client_string_opcode = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 6494 "util/configparser.c" +#line 6546 "util/configparser.c" break; - case 591: /* server_ede: VAR_EDE STRING_ARG */ -#line 3063 "util/configparser.y" + case 592: /* server_ede: VAR_EDE STRING_ARG */ +#line 3070 "util/configparser.y" { OUTYY(("P(server_ede:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6502,21 +6554,33 @@ yyreduce: else cfg_parser->cfg->ede = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6506 "util/configparser.c" +#line 6558 "util/configparser.c" + break; + + case 593: /* server_dns_error_reporting: VAR_DNS_ERROR_REPORTING STRING_ARG */ +#line 3079 "util/configparser.y" + { + OUTYY(("P(server_dns_error_reporting:%s)\n", (yyvsp[0].str))); + if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->dns_error_reporting = (strcmp((yyvsp[0].str), "yes")==0); + free((yyvsp[0].str)); + } +#line 6570 "util/configparser.c" break; - case 592: /* server_proxy_protocol_port: VAR_PROXY_PROTOCOL_PORT STRING_ARG */ -#line 3072 "util/configparser.y" + case 594: /* server_proxy_protocol_port: VAR_PROXY_PROTOCOL_PORT STRING_ARG */ +#line 3088 "util/configparser.y" { OUTYY(("P(server_proxy_protocol_port:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->proxy_protocol_port, (yyvsp[0].str))) yyerror("out of memory"); } -#line 6516 "util/configparser.c" +#line 6580 "util/configparser.c" break; - case 593: /* stub_name: VAR_NAME STRING_ARG */ -#line 3079 "util/configparser.y" + case 595: /* stub_name: VAR_NAME STRING_ARG */ +#line 3095 "util/configparser.y" { OUTYY(("P(name:%s)\n", (yyvsp[0].str))); if(cfg_parser->cfg->stubs->name) @@ -6525,31 +6589,31 @@ yyreduce: free(cfg_parser->cfg->stubs->name); cfg_parser->cfg->stubs->name = (yyvsp[0].str); } -#line 6529 "util/configparser.c" +#line 6593 "util/configparser.c" break; - case 594: /* stub_host: VAR_STUB_HOST STRING_ARG */ -#line 3089 "util/configparser.y" + case 596: /* stub_host: VAR_STUB_HOST STRING_ARG */ +#line 3105 "util/configparser.y" { OUTYY(("P(stub-host:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->hosts, (yyvsp[0].str))) yyerror("out of memory"); } -#line 6539 "util/configparser.c" +#line 6603 "util/configparser.c" break; - case 595: /* stub_addr: VAR_STUB_ADDR STRING_ARG */ -#line 3096 "util/configparser.y" + case 597: /* stub_addr: VAR_STUB_ADDR STRING_ARG */ +#line 3112 "util/configparser.y" { OUTYY(("P(stub-addr:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->stubs->addrs, (yyvsp[0].str))) yyerror("out of memory"); } -#line 6549 "util/configparser.c" +#line 6613 "util/configparser.c" break; - case 596: /* stub_first: VAR_STUB_FIRST STRING_ARG */ -#line 3103 "util/configparser.y" + case 598: /* stub_first: VAR_STUB_FIRST STRING_ARG */ +#line 3119 "util/configparser.y" { OUTYY(("P(stub-first:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6557,11 +6621,11 @@ yyreduce: else cfg_parser->cfg->stubs->isfirst=(strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6561 "util/configparser.c" +#line 6625 "util/configparser.c" break; - case 597: /* stub_no_cache: VAR_STUB_NO_CACHE STRING_ARG */ -#line 3112 "util/configparser.y" + case 599: /* stub_no_cache: VAR_STUB_NO_CACHE STRING_ARG */ +#line 3128 "util/configparser.y" { OUTYY(("P(stub-no-cache:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6569,11 +6633,11 @@ yyreduce: else cfg_parser->cfg->stubs->no_cache=(strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6573 "util/configparser.c" +#line 6637 "util/configparser.c" break; - case 598: /* stub_ssl_upstream: VAR_STUB_SSL_UPSTREAM STRING_ARG */ -#line 3121 "util/configparser.y" + case 600: /* stub_ssl_upstream: VAR_STUB_SSL_UPSTREAM STRING_ARG */ +#line 3137 "util/configparser.y" { OUTYY(("P(stub-ssl-upstream:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6582,11 +6646,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6586 "util/configparser.c" +#line 6650 "util/configparser.c" break; - case 599: /* stub_tcp_upstream: VAR_STUB_TCP_UPSTREAM STRING_ARG */ -#line 3131 "util/configparser.y" + case 601: /* stub_tcp_upstream: VAR_STUB_TCP_UPSTREAM STRING_ARG */ +#line 3147 "util/configparser.y" { OUTYY(("P(stub-tcp-upstream:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6595,11 +6659,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6599 "util/configparser.c" +#line 6663 "util/configparser.c" break; - case 600: /* stub_prime: VAR_STUB_PRIME STRING_ARG */ -#line 3141 "util/configparser.y" + case 602: /* stub_prime: VAR_STUB_PRIME STRING_ARG */ +#line 3157 "util/configparser.y" { OUTYY(("P(stub-prime:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6608,11 +6672,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6612 "util/configparser.c" +#line 6676 "util/configparser.c" break; - case 601: /* forward_name: VAR_NAME STRING_ARG */ -#line 3151 "util/configparser.y" + case 603: /* forward_name: VAR_NAME STRING_ARG */ +#line 3167 "util/configparser.y" { OUTYY(("P(name:%s)\n", (yyvsp[0].str))); if(cfg_parser->cfg->forwards->name) @@ -6621,31 +6685,31 @@ yyreduce: free(cfg_parser->cfg->forwards->name); cfg_parser->cfg->forwards->name = (yyvsp[0].str); } -#line 6625 "util/configparser.c" +#line 6689 "util/configparser.c" break; - case 602: /* forward_host: VAR_FORWARD_HOST STRING_ARG */ -#line 3161 "util/configparser.y" + case 604: /* forward_host: VAR_FORWARD_HOST STRING_ARG */ +#line 3177 "util/configparser.y" { OUTYY(("P(forward-host:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->hosts, (yyvsp[0].str))) yyerror("out of memory"); } -#line 6635 "util/configparser.c" +#line 6699 "util/configparser.c" break; - case 603: /* forward_addr: VAR_FORWARD_ADDR STRING_ARG */ -#line 3168 "util/configparser.y" + case 605: /* forward_addr: VAR_FORWARD_ADDR STRING_ARG */ +#line 3184 "util/configparser.y" { OUTYY(("P(forward-addr:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->forwards->addrs, (yyvsp[0].str))) yyerror("out of memory"); } -#line 6645 "util/configparser.c" +#line 6709 "util/configparser.c" break; - case 604: /* forward_first: VAR_FORWARD_FIRST STRING_ARG */ -#line 3175 "util/configparser.y" + case 606: /* forward_first: VAR_FORWARD_FIRST STRING_ARG */ +#line 3191 "util/configparser.y" { OUTYY(("P(forward-first:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6653,11 +6717,11 @@ yyreduce: else cfg_parser->cfg->forwards->isfirst=(strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6657 "util/configparser.c" +#line 6721 "util/configparser.c" break; - case 605: /* forward_no_cache: VAR_FORWARD_NO_CACHE STRING_ARG */ -#line 3184 "util/configparser.y" + case 607: /* forward_no_cache: VAR_FORWARD_NO_CACHE STRING_ARG */ +#line 3200 "util/configparser.y" { OUTYY(("P(forward-no-cache:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6665,11 +6729,11 @@ yyreduce: else cfg_parser->cfg->forwards->no_cache=(strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6669 "util/configparser.c" +#line 6733 "util/configparser.c" break; - case 606: /* forward_ssl_upstream: VAR_FORWARD_SSL_UPSTREAM STRING_ARG */ -#line 3193 "util/configparser.y" + case 608: /* forward_ssl_upstream: VAR_FORWARD_SSL_UPSTREAM STRING_ARG */ +#line 3209 "util/configparser.y" { OUTYY(("P(forward-ssl-upstream:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6678,11 +6742,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6682 "util/configparser.c" +#line 6746 "util/configparser.c" break; - case 607: /* forward_tcp_upstream: VAR_FORWARD_TCP_UPSTREAM STRING_ARG */ -#line 3203 "util/configparser.y" + case 609: /* forward_tcp_upstream: VAR_FORWARD_TCP_UPSTREAM STRING_ARG */ +#line 3219 "util/configparser.y" { OUTYY(("P(forward-tcp-upstream:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6691,11 +6755,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6695 "util/configparser.c" +#line 6759 "util/configparser.c" break; - case 608: /* auth_name: VAR_NAME STRING_ARG */ -#line 3213 "util/configparser.y" + case 610: /* auth_name: VAR_NAME STRING_ARG */ +#line 3229 "util/configparser.y" { OUTYY(("P(name:%s)\n", (yyvsp[0].str))); if(cfg_parser->cfg->auths->name) @@ -6704,52 +6768,52 @@ yyreduce: free(cfg_parser->cfg->auths->name); cfg_parser->cfg->auths->name = (yyvsp[0].str); } -#line 6708 "util/configparser.c" +#line 6772 "util/configparser.c" break; - case 609: /* auth_zonefile: VAR_ZONEFILE STRING_ARG */ -#line 3223 "util/configparser.y" + case 611: /* auth_zonefile: VAR_ZONEFILE STRING_ARG */ +#line 3239 "util/configparser.y" { OUTYY(("P(zonefile:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->auths->zonefile); cfg_parser->cfg->auths->zonefile = (yyvsp[0].str); } -#line 6718 "util/configparser.c" +#line 6782 "util/configparser.c" break; - case 610: /* auth_master: VAR_MASTER STRING_ARG */ -#line 3230 "util/configparser.y" + case 612: /* auth_master: VAR_MASTER STRING_ARG */ +#line 3246 "util/configparser.y" { OUTYY(("P(master:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->auths->masters, (yyvsp[0].str))) yyerror("out of memory"); } -#line 6728 "util/configparser.c" +#line 6792 "util/configparser.c" break; - case 611: /* auth_url: VAR_URL STRING_ARG */ -#line 3237 "util/configparser.y" + case 613: /* auth_url: VAR_URL STRING_ARG */ +#line 3253 "util/configparser.y" { OUTYY(("P(url:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->auths->urls, (yyvsp[0].str))) yyerror("out of memory"); } -#line 6738 "util/configparser.c" +#line 6802 "util/configparser.c" break; - case 612: /* auth_allow_notify: VAR_ALLOW_NOTIFY STRING_ARG */ -#line 3244 "util/configparser.y" + case 614: /* auth_allow_notify: VAR_ALLOW_NOTIFY STRING_ARG */ +#line 3260 "util/configparser.y" { OUTYY(("P(allow-notify:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->auths->allow_notify, (yyvsp[0].str))) yyerror("out of memory"); } -#line 6749 "util/configparser.c" +#line 6813 "util/configparser.c" break; - case 613: /* auth_zonemd_check: VAR_ZONEMD_CHECK STRING_ARG */ -#line 3252 "util/configparser.y" + case 615: /* auth_zonemd_check: VAR_ZONEMD_CHECK STRING_ARG */ +#line 3268 "util/configparser.y" { OUTYY(("P(zonemd-check:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6758,11 +6822,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6762 "util/configparser.c" +#line 6826 "util/configparser.c" break; - case 614: /* auth_zonemd_reject_absence: VAR_ZONEMD_REJECT_ABSENCE STRING_ARG */ -#line 3262 "util/configparser.y" + case 616: /* auth_zonemd_reject_absence: VAR_ZONEMD_REJECT_ABSENCE STRING_ARG */ +#line 3278 "util/configparser.y" { OUTYY(("P(zonemd-reject-absence:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6771,11 +6835,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6775 "util/configparser.c" +#line 6839 "util/configparser.c" break; - case 615: /* auth_for_downstream: VAR_FOR_DOWNSTREAM STRING_ARG */ -#line 3272 "util/configparser.y" + case 617: /* auth_for_downstream: VAR_FOR_DOWNSTREAM STRING_ARG */ +#line 3288 "util/configparser.y" { OUTYY(("P(for-downstream:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6784,11 +6848,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6788 "util/configparser.c" +#line 6852 "util/configparser.c" break; - case 616: /* auth_for_upstream: VAR_FOR_UPSTREAM STRING_ARG */ -#line 3282 "util/configparser.y" + case 618: /* auth_for_upstream: VAR_FOR_UPSTREAM STRING_ARG */ +#line 3298 "util/configparser.y" { OUTYY(("P(for-upstream:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6797,11 +6861,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6801 "util/configparser.c" +#line 6865 "util/configparser.c" break; - case 617: /* auth_fallback_enabled: VAR_FALLBACK_ENABLED STRING_ARG */ -#line 3292 "util/configparser.y" + case 619: /* auth_fallback_enabled: VAR_FALLBACK_ENABLED STRING_ARG */ +#line 3308 "util/configparser.y" { OUTYY(("P(fallback-enabled:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6810,11 +6874,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6814 "util/configparser.c" +#line 6878 "util/configparser.c" break; - case 618: /* view_name: VAR_NAME STRING_ARG */ -#line 3302 "util/configparser.y" + case 620: /* view_name: VAR_NAME STRING_ARG */ +#line 3318 "util/configparser.y" { OUTYY(("P(name:%s)\n", (yyvsp[0].str))); if(cfg_parser->cfg->views->name) @@ -6823,11 +6887,11 @@ yyreduce: free(cfg_parser->cfg->views->name); cfg_parser->cfg->views->name = (yyvsp[0].str); } -#line 6827 "util/configparser.c" +#line 6891 "util/configparser.c" break; - case 619: /* view_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG */ -#line 3312 "util/configparser.y" + case 621: /* view_local_zone: VAR_LOCAL_ZONE STRING_ARG STRING_ARG */ +#line 3328 "util/configparser.y" { OUTYY(("P(view_local_zone:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "static")!=0 && strcmp((yyvsp[0].str), "deny")!=0 && @@ -6882,11 +6946,11 @@ yyreduce: fatal_exit("out of memory adding local-zone"); } } -#line 6886 "util/configparser.c" +#line 6950 "util/configparser.c" break; - case 620: /* view_response_ip: VAR_RESPONSE_IP STRING_ARG STRING_ARG */ -#line 3368 "util/configparser.y" + case 622: /* view_response_ip: VAR_RESPONSE_IP STRING_ARG STRING_ARG */ +#line 3384 "util/configparser.y" { OUTYY(("P(view_response_ip:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); validate_respip_action((yyvsp[0].str)); @@ -6895,33 +6959,33 @@ yyreduce: fatal_exit("out of memory adding per-view " "response-ip action"); } -#line 6899 "util/configparser.c" +#line 6963 "util/configparser.c" break; - case 621: /* view_response_ip_data: VAR_RESPONSE_IP_DATA STRING_ARG STRING_ARG */ -#line 3378 "util/configparser.y" + case 623: /* view_response_ip_data: VAR_RESPONSE_IP_DATA STRING_ARG STRING_ARG */ +#line 3394 "util/configparser.y" { OUTYY(("P(view_response_ip_data:%s)\n", (yyvsp[-1].str))); if(!cfg_str2list_insert( &cfg_parser->cfg->views->respip_data, (yyvsp[-1].str), (yyvsp[0].str))) fatal_exit("out of memory adding response-ip-data"); } -#line 6910 "util/configparser.c" +#line 6974 "util/configparser.c" break; - case 622: /* view_local_data: VAR_LOCAL_DATA STRING_ARG */ -#line 3386 "util/configparser.y" + case 624: /* view_local_data: VAR_LOCAL_DATA STRING_ARG */ +#line 3402 "util/configparser.y" { OUTYY(("P(view_local_data:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->views->local_data, (yyvsp[0].str))) { fatal_exit("out of memory adding local-data"); } } -#line 6921 "util/configparser.c" +#line 6985 "util/configparser.c" break; - case 623: /* view_local_data_ptr: VAR_LOCAL_DATA_PTR STRING_ARG */ -#line 3394 "util/configparser.y" + case 625: /* view_local_data_ptr: VAR_LOCAL_DATA_PTR STRING_ARG */ +#line 3410 "util/configparser.y" { char* ptr; OUTYY(("P(view_local_data_ptr:%s)\n", (yyvsp[0].str))); @@ -6935,11 +6999,11 @@ yyreduce: yyerror("local-data-ptr could not be reversed"); } } -#line 6939 "util/configparser.c" +#line 7003 "util/configparser.c" break; - case 624: /* view_first: VAR_VIEW_FIRST STRING_ARG */ -#line 3409 "util/configparser.y" + case 626: /* view_first: VAR_VIEW_FIRST STRING_ARG */ +#line 3425 "util/configparser.y" { OUTYY(("P(view-first:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6947,20 +7011,20 @@ yyreduce: else cfg_parser->cfg->views->isfirst=(strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6951 "util/configparser.c" +#line 7015 "util/configparser.c" break; - case 625: /* rcstart: VAR_REMOTE_CONTROL */ -#line 3418 "util/configparser.y" + case 627: /* rcstart: VAR_REMOTE_CONTROL */ +#line 3434 "util/configparser.y" { OUTYY(("\nP(remote-control:)\n")); cfg_parser->started_toplevel = 1; } -#line 6960 "util/configparser.c" +#line 7024 "util/configparser.c" break; - case 636: /* rc_control_enable: VAR_CONTROL_ENABLE STRING_ARG */ -#line 3430 "util/configparser.y" + case 638: /* rc_control_enable: VAR_CONTROL_ENABLE STRING_ARG */ +#line 3446 "util/configparser.y" { OUTYY(("P(control_enable:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -6969,11 +7033,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 6973 "util/configparser.c" +#line 7037 "util/configparser.c" break; - case 637: /* rc_control_port: VAR_CONTROL_PORT STRING_ARG */ -#line 3440 "util/configparser.y" + case 639: /* rc_control_port: VAR_CONTROL_PORT STRING_ARG */ +#line 3456 "util/configparser.y" { OUTYY(("P(control_port:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -6981,80 +7045,80 @@ yyreduce: else cfg_parser->cfg->control_port = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 6985 "util/configparser.c" +#line 7049 "util/configparser.c" break; - case 638: /* rc_control_interface: VAR_CONTROL_INTERFACE STRING_ARG */ -#line 3449 "util/configparser.y" + case 640: /* rc_control_interface: VAR_CONTROL_INTERFACE STRING_ARG */ +#line 3465 "util/configparser.y" { OUTYY(("P(control_interface:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_append(&cfg_parser->cfg->control_ifs, (yyvsp[0].str))) yyerror("out of memory"); } -#line 6995 "util/configparser.c" +#line 7059 "util/configparser.c" break; - case 639: /* rc_control_use_cert: VAR_CONTROL_USE_CERT STRING_ARG */ -#line 3456 "util/configparser.y" + case 641: /* rc_control_use_cert: VAR_CONTROL_USE_CERT STRING_ARG */ +#line 3472 "util/configparser.y" { OUTYY(("P(control_use_cert:%s)\n", (yyvsp[0].str))); cfg_parser->cfg->control_use_cert = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 7005 "util/configparser.c" +#line 7069 "util/configparser.c" break; - case 640: /* rc_server_key_file: VAR_SERVER_KEY_FILE STRING_ARG */ -#line 3463 "util/configparser.y" + case 642: /* rc_server_key_file: VAR_SERVER_KEY_FILE STRING_ARG */ +#line 3479 "util/configparser.y" { OUTYY(("P(rc_server_key_file:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->server_key_file); cfg_parser->cfg->server_key_file = (yyvsp[0].str); } -#line 7015 "util/configparser.c" +#line 7079 "util/configparser.c" break; - case 641: /* rc_server_cert_file: VAR_SERVER_CERT_FILE STRING_ARG */ -#line 3470 "util/configparser.y" + case 643: /* rc_server_cert_file: VAR_SERVER_CERT_FILE STRING_ARG */ +#line 3486 "util/configparser.y" { OUTYY(("P(rc_server_cert_file:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->server_cert_file); cfg_parser->cfg->server_cert_file = (yyvsp[0].str); } -#line 7025 "util/configparser.c" +#line 7089 "util/configparser.c" break; - case 642: /* rc_control_key_file: VAR_CONTROL_KEY_FILE STRING_ARG */ -#line 3477 "util/configparser.y" + case 644: /* rc_control_key_file: VAR_CONTROL_KEY_FILE STRING_ARG */ +#line 3493 "util/configparser.y" { OUTYY(("P(rc_control_key_file:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->control_key_file); cfg_parser->cfg->control_key_file = (yyvsp[0].str); } -#line 7035 "util/configparser.c" +#line 7099 "util/configparser.c" break; - case 643: /* rc_control_cert_file: VAR_CONTROL_CERT_FILE STRING_ARG */ -#line 3484 "util/configparser.y" + case 645: /* rc_control_cert_file: VAR_CONTROL_CERT_FILE STRING_ARG */ +#line 3500 "util/configparser.y" { OUTYY(("P(rc_control_cert_file:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->control_cert_file); cfg_parser->cfg->control_cert_file = (yyvsp[0].str); } -#line 7045 "util/configparser.c" +#line 7109 "util/configparser.c" break; - case 644: /* dtstart: VAR_DNSTAP */ -#line 3491 "util/configparser.y" + case 646: /* dtstart: VAR_DNSTAP */ +#line 3507 "util/configparser.y" { OUTYY(("\nP(dnstap:)\n")); cfg_parser->started_toplevel = 1; } -#line 7054 "util/configparser.c" +#line 7118 "util/configparser.c" break; - case 667: /* dt_dnstap_enable: VAR_DNSTAP_ENABLE STRING_ARG */ -#line 3513 "util/configparser.y" + case 669: /* dt_dnstap_enable: VAR_DNSTAP_ENABLE STRING_ARG */ +#line 3529 "util/configparser.y" { OUTYY(("P(dt_dnstap_enable:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -7062,11 +7126,11 @@ yyreduce: else cfg_parser->cfg->dnstap = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 7066 "util/configparser.c" +#line 7130 "util/configparser.c" break; - case 668: /* dt_dnstap_bidirectional: VAR_DNSTAP_BIDIRECTIONAL STRING_ARG */ -#line 3522 "util/configparser.y" + case 670: /* dt_dnstap_bidirectional: VAR_DNSTAP_BIDIRECTIONAL STRING_ARG */ +#line 3538 "util/configparser.y" { OUTYY(("P(dt_dnstap_bidirectional:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -7075,31 +7139,31 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 7079 "util/configparser.c" +#line 7143 "util/configparser.c" break; - case 669: /* dt_dnstap_socket_path: VAR_DNSTAP_SOCKET_PATH STRING_ARG */ -#line 3532 "util/configparser.y" + case 671: /* dt_dnstap_socket_path: VAR_DNSTAP_SOCKET_PATH STRING_ARG */ +#line 3548 "util/configparser.y" { OUTYY(("P(dt_dnstap_socket_path:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dnstap_socket_path); cfg_parser->cfg->dnstap_socket_path = (yyvsp[0].str); } -#line 7089 "util/configparser.c" +#line 7153 "util/configparser.c" break; - case 670: /* dt_dnstap_ip: VAR_DNSTAP_IP STRING_ARG */ -#line 3539 "util/configparser.y" + case 672: /* dt_dnstap_ip: VAR_DNSTAP_IP STRING_ARG */ +#line 3555 "util/configparser.y" { OUTYY(("P(dt_dnstap_ip:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dnstap_ip); cfg_parser->cfg->dnstap_ip = (yyvsp[0].str); } -#line 7099 "util/configparser.c" +#line 7163 "util/configparser.c" break; - case 671: /* dt_dnstap_tls: VAR_DNSTAP_TLS STRING_ARG */ -#line 3546 "util/configparser.y" + case 673: /* dt_dnstap_tls: VAR_DNSTAP_TLS STRING_ARG */ +#line 3562 "util/configparser.y" { OUTYY(("P(dt_dnstap_tls:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -7107,51 +7171,51 @@ yyreduce: else cfg_parser->cfg->dnstap_tls = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 7111 "util/configparser.c" +#line 7175 "util/configparser.c" break; - case 672: /* dt_dnstap_tls_server_name: VAR_DNSTAP_TLS_SERVER_NAME STRING_ARG */ -#line 3555 "util/configparser.y" + case 674: /* dt_dnstap_tls_server_name: VAR_DNSTAP_TLS_SERVER_NAME STRING_ARG */ +#line 3571 "util/configparser.y" { OUTYY(("P(dt_dnstap_tls_server_name:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dnstap_tls_server_name); cfg_parser->cfg->dnstap_tls_server_name = (yyvsp[0].str); } -#line 7121 "util/configparser.c" +#line 7185 "util/configparser.c" break; - case 673: /* dt_dnstap_tls_cert_bundle: VAR_DNSTAP_TLS_CERT_BUNDLE STRING_ARG */ -#line 3562 "util/configparser.y" + case 675: /* dt_dnstap_tls_cert_bundle: VAR_DNSTAP_TLS_CERT_BUNDLE STRING_ARG */ +#line 3578 "util/configparser.y" { OUTYY(("P(dt_dnstap_tls_cert_bundle:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dnstap_tls_cert_bundle); cfg_parser->cfg->dnstap_tls_cert_bundle = (yyvsp[0].str); } -#line 7131 "util/configparser.c" +#line 7195 "util/configparser.c" break; - case 674: /* dt_dnstap_tls_client_key_file: VAR_DNSTAP_TLS_CLIENT_KEY_FILE STRING_ARG */ -#line 3569 "util/configparser.y" + case 676: /* dt_dnstap_tls_client_key_file: VAR_DNSTAP_TLS_CLIENT_KEY_FILE STRING_ARG */ +#line 3585 "util/configparser.y" { OUTYY(("P(dt_dnstap_tls_client_key_file:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dnstap_tls_client_key_file); cfg_parser->cfg->dnstap_tls_client_key_file = (yyvsp[0].str); } -#line 7141 "util/configparser.c" +#line 7205 "util/configparser.c" break; - case 675: /* dt_dnstap_tls_client_cert_file: VAR_DNSTAP_TLS_CLIENT_CERT_FILE STRING_ARG */ -#line 3576 "util/configparser.y" + case 677: /* dt_dnstap_tls_client_cert_file: VAR_DNSTAP_TLS_CLIENT_CERT_FILE STRING_ARG */ +#line 3592 "util/configparser.y" { OUTYY(("P(dt_dnstap_tls_client_cert_file:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dnstap_tls_client_cert_file); cfg_parser->cfg->dnstap_tls_client_cert_file = (yyvsp[0].str); } -#line 7151 "util/configparser.c" +#line 7215 "util/configparser.c" break; - case 676: /* dt_dnstap_send_identity: VAR_DNSTAP_SEND_IDENTITY STRING_ARG */ -#line 3583 "util/configparser.y" + case 678: /* dt_dnstap_send_identity: VAR_DNSTAP_SEND_IDENTITY STRING_ARG */ +#line 3599 "util/configparser.y" { OUTYY(("P(dt_dnstap_send_identity:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -7159,11 +7223,11 @@ yyreduce: else cfg_parser->cfg->dnstap_send_identity = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 7163 "util/configparser.c" +#line 7227 "util/configparser.c" break; - case 677: /* dt_dnstap_send_version: VAR_DNSTAP_SEND_VERSION STRING_ARG */ -#line 3592 "util/configparser.y" + case 679: /* dt_dnstap_send_version: VAR_DNSTAP_SEND_VERSION STRING_ARG */ +#line 3608 "util/configparser.y" { OUTYY(("P(dt_dnstap_send_version:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -7171,31 +7235,31 @@ yyreduce: else cfg_parser->cfg->dnstap_send_version = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 7175 "util/configparser.c" +#line 7239 "util/configparser.c" break; - case 678: /* dt_dnstap_identity: VAR_DNSTAP_IDENTITY STRING_ARG */ -#line 3601 "util/configparser.y" + case 680: /* dt_dnstap_identity: VAR_DNSTAP_IDENTITY STRING_ARG */ +#line 3617 "util/configparser.y" { OUTYY(("P(dt_dnstap_identity:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dnstap_identity); cfg_parser->cfg->dnstap_identity = (yyvsp[0].str); } -#line 7185 "util/configparser.c" +#line 7249 "util/configparser.c" break; - case 679: /* dt_dnstap_version: VAR_DNSTAP_VERSION STRING_ARG */ -#line 3608 "util/configparser.y" + case 681: /* dt_dnstap_version: VAR_DNSTAP_VERSION STRING_ARG */ +#line 3624 "util/configparser.y" { OUTYY(("P(dt_dnstap_version:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dnstap_version); cfg_parser->cfg->dnstap_version = (yyvsp[0].str); } -#line 7195 "util/configparser.c" +#line 7259 "util/configparser.c" break; - case 680: /* dt_dnstap_log_resolver_query_messages: VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES STRING_ARG */ -#line 3615 "util/configparser.y" + case 682: /* dt_dnstap_log_resolver_query_messages: VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES STRING_ARG */ +#line 3631 "util/configparser.y" { OUTYY(("P(dt_dnstap_log_resolver_query_messages:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -7204,11 +7268,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 7208 "util/configparser.c" +#line 7272 "util/configparser.c" break; - case 681: /* dt_dnstap_log_resolver_response_messages: VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES STRING_ARG */ -#line 3625 "util/configparser.y" + case 683: /* dt_dnstap_log_resolver_response_messages: VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES STRING_ARG */ +#line 3641 "util/configparser.y" { OUTYY(("P(dt_dnstap_log_resolver_response_messages:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -7217,11 +7281,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 7221 "util/configparser.c" +#line 7285 "util/configparser.c" break; - case 682: /* dt_dnstap_log_client_query_messages: VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES STRING_ARG */ -#line 3635 "util/configparser.y" + case 684: /* dt_dnstap_log_client_query_messages: VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES STRING_ARG */ +#line 3651 "util/configparser.y" { OUTYY(("P(dt_dnstap_log_client_query_messages:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -7230,11 +7294,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 7234 "util/configparser.c" +#line 7298 "util/configparser.c" break; - case 683: /* dt_dnstap_log_client_response_messages: VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES STRING_ARG */ -#line 3645 "util/configparser.y" + case 685: /* dt_dnstap_log_client_response_messages: VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES STRING_ARG */ +#line 3661 "util/configparser.y" { OUTYY(("P(dt_dnstap_log_client_response_messages:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -7243,11 +7307,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 7247 "util/configparser.c" +#line 7311 "util/configparser.c" break; - case 684: /* dt_dnstap_log_forwarder_query_messages: VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES STRING_ARG */ -#line 3655 "util/configparser.y" + case 686: /* dt_dnstap_log_forwarder_query_messages: VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES STRING_ARG */ +#line 3671 "util/configparser.y" { OUTYY(("P(dt_dnstap_log_forwarder_query_messages:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -7256,11 +7320,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 7260 "util/configparser.c" +#line 7324 "util/configparser.c" break; - case 685: /* dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES STRING_ARG */ -#line 3665 "util/configparser.y" + case 687: /* dt_dnstap_log_forwarder_response_messages: VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES STRING_ARG */ +#line 3681 "util/configparser.y" { OUTYY(("P(dt_dnstap_log_forwarder_response_messages:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -7269,11 +7333,11 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 7273 "util/configparser.c" +#line 7337 "util/configparser.c" break; - case 686: /* dt_dnstap_sample_rate: VAR_DNSTAP_SAMPLE_RATE STRING_ARG */ -#line 3675 "util/configparser.y" + case 688: /* dt_dnstap_sample_rate: VAR_DNSTAP_SAMPLE_RATE STRING_ARG */ +#line 3691 "util/configparser.y" { OUTYY(("P(dt_dnstap_sample_rate:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -7283,49 +7347,49 @@ yyreduce: else cfg_parser->cfg->dnstap_sample_rate = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 7287 "util/configparser.c" +#line 7351 "util/configparser.c" break; - case 687: /* pythonstart: VAR_PYTHON */ -#line 3686 "util/configparser.y" + case 689: /* pythonstart: VAR_PYTHON */ +#line 3702 "util/configparser.y" { OUTYY(("\nP(python:)\n")); cfg_parser->started_toplevel = 1; } -#line 7296 "util/configparser.c" +#line 7360 "util/configparser.c" break; - case 691: /* py_script: VAR_PYTHON_SCRIPT STRING_ARG */ -#line 3696 "util/configparser.y" + case 693: /* py_script: VAR_PYTHON_SCRIPT STRING_ARG */ +#line 3712 "util/configparser.y" { OUTYY(("P(python-script:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_append_ex(&cfg_parser->cfg->python_script, (yyvsp[0].str))) yyerror("out of memory"); } -#line 7306 "util/configparser.c" +#line 7370 "util/configparser.c" break; - case 692: /* dynlibstart: VAR_DYNLIB */ -#line 3703 "util/configparser.y" + case 694: /* dynlibstart: VAR_DYNLIB */ +#line 3719 "util/configparser.y" { OUTYY(("\nP(dynlib:)\n")); cfg_parser->started_toplevel = 1; } -#line 7315 "util/configparser.c" +#line 7379 "util/configparser.c" break; - case 696: /* dl_file: VAR_DYNLIB_FILE STRING_ARG */ -#line 3713 "util/configparser.y" + case 698: /* dl_file: VAR_DYNLIB_FILE STRING_ARG */ +#line 3729 "util/configparser.y" { OUTYY(("P(dynlib-file:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_append_ex(&cfg_parser->cfg->dynlib_file, (yyvsp[0].str))) yyerror("out of memory"); } -#line 7325 "util/configparser.c" +#line 7389 "util/configparser.c" break; - case 697: /* server_disable_dnssec_lame_check: VAR_DISABLE_DNSSEC_LAME_CHECK STRING_ARG */ -#line 3720 "util/configparser.y" + case 699: /* server_disable_dnssec_lame_check: VAR_DISABLE_DNSSEC_LAME_CHECK STRING_ARG */ +#line 3736 "util/configparser.y" { OUTYY(("P(disable_dnssec_lame_check:%s)\n", (yyvsp[0].str))); if (strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -7334,21 +7398,21 @@ yyreduce: (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 7338 "util/configparser.c" +#line 7402 "util/configparser.c" break; - case 698: /* server_log_identity: VAR_LOG_IDENTITY STRING_ARG */ -#line 3730 "util/configparser.y" + case 700: /* server_log_identity: VAR_LOG_IDENTITY STRING_ARG */ +#line 3746 "util/configparser.y" { OUTYY(("P(server_log_identity:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->log_identity); cfg_parser->cfg->log_identity = (yyvsp[0].str); } -#line 7348 "util/configparser.c" +#line 7412 "util/configparser.c" break; - case 699: /* server_response_ip: VAR_RESPONSE_IP STRING_ARG STRING_ARG */ -#line 3737 "util/configparser.y" + case 701: /* server_response_ip: VAR_RESPONSE_IP STRING_ARG STRING_ARG */ +#line 3753 "util/configparser.y" { OUTYY(("P(server_response_ip:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); validate_respip_action((yyvsp[0].str)); @@ -7356,31 +7420,31 @@ yyreduce: (yyvsp[-1].str), (yyvsp[0].str))) fatal_exit("out of memory adding response-ip"); } -#line 7360 "util/configparser.c" +#line 7424 "util/configparser.c" break; - case 700: /* server_response_ip_data: VAR_RESPONSE_IP_DATA STRING_ARG STRING_ARG */ -#line 3746 "util/configparser.y" + case 702: /* server_response_ip_data: VAR_RESPONSE_IP_DATA STRING_ARG STRING_ARG */ +#line 3762 "util/configparser.y" { OUTYY(("P(server_response_ip_data:%s)\n", (yyvsp[-1].str))); if(!cfg_str2list_insert(&cfg_parser->cfg->respip_data, (yyvsp[-1].str), (yyvsp[0].str))) fatal_exit("out of memory adding response-ip-data"); } -#line 7371 "util/configparser.c" +#line 7435 "util/configparser.c" break; - case 701: /* dnscstart: VAR_DNSCRYPT */ -#line 3754 "util/configparser.y" + case 703: /* dnscstart: VAR_DNSCRYPT */ +#line 3770 "util/configparser.y" { OUTYY(("\nP(dnscrypt:)\n")); cfg_parser->started_toplevel = 1; } -#line 7380 "util/configparser.c" +#line 7444 "util/configparser.c" break; - case 714: /* dnsc_dnscrypt_enable: VAR_DNSCRYPT_ENABLE STRING_ARG */ -#line 3771 "util/configparser.y" + case 716: /* dnsc_dnscrypt_enable: VAR_DNSCRYPT_ENABLE STRING_ARG */ +#line 3787 "util/configparser.y" { OUTYY(("P(dnsc_dnscrypt_enable:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -7388,11 +7452,11 @@ yyreduce: else cfg_parser->cfg->dnscrypt = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 7392 "util/configparser.c" +#line 7456 "util/configparser.c" break; - case 715: /* dnsc_dnscrypt_port: VAR_DNSCRYPT_PORT STRING_ARG */ -#line 3780 "util/configparser.y" + case 717: /* dnsc_dnscrypt_port: VAR_DNSCRYPT_PORT STRING_ARG */ +#line 3796 "util/configparser.y" { OUTYY(("P(dnsc_dnscrypt_port:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) @@ -7400,21 +7464,21 @@ yyreduce: else cfg_parser->cfg->dnscrypt_port = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 7404 "util/configparser.c" +#line 7468 "util/configparser.c" break; - case 716: /* dnsc_dnscrypt_provider: VAR_DNSCRYPT_PROVIDER STRING_ARG */ -#line 3789 "util/configparser.y" + case 718: /* dnsc_dnscrypt_provider: VAR_DNSCRYPT_PROVIDER STRING_ARG */ +#line 3805 "util/configparser.y" { OUTYY(("P(dnsc_dnscrypt_provider:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->dnscrypt_provider); cfg_parser->cfg->dnscrypt_provider = (yyvsp[0].str); } -#line 7414 "util/configparser.c" +#line 7478 "util/configparser.c" break; - case 717: /* dnsc_dnscrypt_provider_cert: VAR_DNSCRYPT_PROVIDER_CERT STRING_ARG */ -#line 3796 "util/configparser.y" + case 719: /* dnsc_dnscrypt_provider_cert: VAR_DNSCRYPT_PROVIDER_CERT STRING_ARG */ +#line 3812 "util/configparser.y" { OUTYY(("P(dnsc_dnscrypt_provider_cert:%s)\n", (yyvsp[0].str))); if(cfg_strlist_find(cfg_parser->cfg->dnscrypt_provider_cert, (yyvsp[0].str))) @@ -7422,21 +7486,21 @@ yyreduce: if(!cfg_strlist_insert(&cfg_parser->cfg->dnscrypt_provider_cert, (yyvsp[0].str))) fatal_exit("out of memory adding dnscrypt-provider-cert"); } -#line 7426 "util/configparser.c" +#line 7490 "util/configparser.c" break; - case 718: /* dnsc_dnscrypt_provider_cert_rotated: VAR_DNSCRYPT_PROVIDER_CERT_ROTATED STRING_ARG */ -#line 3805 "util/configparser.y" + case 720: /* dnsc_dnscrypt_provider_cert_rotated: VAR_DNSCRYPT_PROVIDER_CERT_ROTATED STRING_ARG */ +#line 3821 "util/configparser.y" { OUTYY(("P(dnsc_dnscrypt_provider_cert_rotated:%s)\n", (yyvsp[0].str))); if(!cfg_strlist_insert(&cfg_parser->cfg->dnscrypt_provider_cert_rotated, (yyvsp[0].str))) fatal_exit("out of memory adding dnscrypt-provider-cert-rotated"); } -#line 7436 "util/configparser.c" +#line 7500 "util/configparser.c" break; - case 719: /* dnsc_dnscrypt_secret_key: VAR_DNSCRYPT_SECRET_KEY STRING_ARG */ -#line 3812 "util/configparser.y" + case 721: /* dnsc_dnscrypt_secret_key: VAR_DNSCRYPT_SECRET_KEY STRING_ARG */ +#line 3828 "util/configparser.y" { OUTYY(("P(dnsc_dnscrypt_secret_key:%s)\n", (yyvsp[0].str))); if(cfg_strlist_find(cfg_parser->cfg->dnscrypt_secret_key, (yyvsp[0].str))) @@ -7444,22 +7508,22 @@ yyreduce: if(!cfg_strlist_insert(&cfg_parser->cfg->dnscrypt_secret_key, (yyvsp[0].str))) fatal_exit("out of memory adding dnscrypt-secret-key"); } -#line 7448 "util/configparser.c" +#line 7512 "util/configparser.c" break; - case 720: /* dnsc_dnscrypt_shared_secret_cache_size: VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE STRING_ARG */ -#line 3821 "util/configparser.y" + case 722: /* dnsc_dnscrypt_shared_secret_cache_size: VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE STRING_ARG */ +#line 3837 "util/configparser.y" { OUTYY(("P(dnscrypt_shared_secret_cache_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->dnscrypt_shared_secret_cache_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 7459 "util/configparser.c" +#line 7523 "util/configparser.c" break; - case 721: /* dnsc_dnscrypt_shared_secret_cache_slabs: VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS STRING_ARG */ -#line 3829 "util/configparser.y" + case 723: /* dnsc_dnscrypt_shared_secret_cache_slabs: VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS STRING_ARG */ +#line 3845 "util/configparser.y" { OUTYY(("P(dnscrypt_shared_secret_cache_slabs:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) { @@ -7471,22 +7535,22 @@ yyreduce: } free((yyvsp[0].str)); } -#line 7475 "util/configparser.c" +#line 7539 "util/configparser.c" break; - case 722: /* dnsc_dnscrypt_nonce_cache_size: VAR_DNSCRYPT_NONCE_CACHE_SIZE STRING_ARG */ -#line 3842 "util/configparser.y" + case 724: /* dnsc_dnscrypt_nonce_cache_size: VAR_DNSCRYPT_NONCE_CACHE_SIZE STRING_ARG */ +#line 3858 "util/configparser.y" { OUTYY(("P(dnscrypt_nonce_cache_size:%s)\n", (yyvsp[0].str))); if(!cfg_parse_memsize((yyvsp[0].str), &cfg_parser->cfg->dnscrypt_nonce_cache_size)) yyerror("memory size expected"); free((yyvsp[0].str)); } -#line 7486 "util/configparser.c" +#line 7550 "util/configparser.c" break; - case 723: /* dnsc_dnscrypt_nonce_cache_slabs: VAR_DNSCRYPT_NONCE_CACHE_SLABS STRING_ARG */ -#line 3850 "util/configparser.y" + case 725: /* dnsc_dnscrypt_nonce_cache_slabs: VAR_DNSCRYPT_NONCE_CACHE_SLABS STRING_ARG */ +#line 3866 "util/configparser.y" { OUTYY(("P(dnscrypt_nonce_cache_slabs:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0) { @@ -7498,20 +7562,20 @@ yyreduce: } free((yyvsp[0].str)); } -#line 7502 "util/configparser.c" +#line 7566 "util/configparser.c" break; - case 724: /* cachedbstart: VAR_CACHEDB */ -#line 3863 "util/configparser.y" + case 726: /* cachedbstart: VAR_CACHEDB */ +#line 3879 "util/configparser.y" { OUTYY(("\nP(cachedb:)\n")); cfg_parser->started_toplevel = 1; } -#line 7511 "util/configparser.c" +#line 7575 "util/configparser.c" break; - case 740: /* cachedb_backend_name: VAR_CACHEDB_BACKEND STRING_ARG */ -#line 3877 "util/configparser.y" + case 750: /* cachedb_backend_name: VAR_CACHEDB_BACKEND STRING_ARG */ +#line 3899 "util/configparser.y" { #ifdef USE_CACHEDB OUTYY(("P(backend:%s)\n", (yyvsp[0].str))); @@ -7522,11 +7586,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 7526 "util/configparser.c" +#line 7590 "util/configparser.c" break; - case 741: /* cachedb_secret_seed: VAR_CACHEDB_SECRETSEED STRING_ARG */ -#line 3889 "util/configparser.y" + case 751: /* cachedb_secret_seed: VAR_CACHEDB_SECRETSEED STRING_ARG */ +#line 3911 "util/configparser.y" { #ifdef USE_CACHEDB OUTYY(("P(secret-seed:%s)\n", (yyvsp[0].str))); @@ -7537,11 +7601,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 7541 "util/configparser.c" +#line 7605 "util/configparser.c" break; - case 742: /* cachedb_no_store: VAR_CACHEDB_NO_STORE STRING_ARG */ -#line 3901 "util/configparser.y" + case 752: /* cachedb_no_store: VAR_CACHEDB_NO_STORE STRING_ARG */ +#line 3923 "util/configparser.y" { #ifdef USE_CACHEDB OUTYY(("P(cachedb_no_store:%s)\n", (yyvsp[0].str))); @@ -7553,11 +7617,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 7557 "util/configparser.c" +#line 7621 "util/configparser.c" break; - case 743: /* cachedb_check_when_serve_expired: VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED STRING_ARG */ -#line 3914 "util/configparser.y" + case 753: /* cachedb_check_when_serve_expired: VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED STRING_ARG */ +#line 3936 "util/configparser.y" { #ifdef USE_CACHEDB OUTYY(("P(cachedb_check_when_serve_expired:%s)\n", (yyvsp[0].str))); @@ -7569,11 +7633,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 7573 "util/configparser.c" +#line 7637 "util/configparser.c" break; - case 744: /* redis_server_host: VAR_CACHEDB_REDISHOST STRING_ARG */ -#line 3927 "util/configparser.y" + case 754: /* redis_server_host: VAR_CACHEDB_REDISHOST STRING_ARG */ +#line 3949 "util/configparser.y" { #if defined(USE_CACHEDB) && defined(USE_REDIS) OUTYY(("P(redis_server_host:%s)\n", (yyvsp[0].str))); @@ -7584,11 +7648,26 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 7588 "util/configparser.c" +#line 7652 "util/configparser.c" + break; + + case 755: /* redis_replica_server_host: VAR_CACHEDB_REDISREPLICAHOST STRING_ARG */ +#line 3961 "util/configparser.y" + { + #if defined(USE_CACHEDB) && defined(USE_REDIS) + OUTYY(("P(redis_replica_server_host:%s)\n", (yyvsp[0].str))); + free(cfg_parser->cfg->redis_replica_server_host); + cfg_parser->cfg->redis_replica_server_host = (yyvsp[0].str); + #else + OUTYY(("P(Compiled without cachedb or redis, ignoring)\n")); + free((yyvsp[0].str)); + #endif + } +#line 7667 "util/configparser.c" break; - case 745: /* redis_server_port: VAR_CACHEDB_REDISPORT STRING_ARG */ -#line 3939 "util/configparser.y" + case 756: /* redis_server_port: VAR_CACHEDB_REDISPORT STRING_ARG */ +#line 3973 "util/configparser.y" { #if defined(USE_CACHEDB) && defined(USE_REDIS) int port; @@ -7602,11 +7681,29 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 7606 "util/configparser.c" +#line 7685 "util/configparser.c" + break; + + case 757: /* redis_replica_server_port: VAR_CACHEDB_REDISREPLICAPORT STRING_ARG */ +#line 3988 "util/configparser.y" + { + #if defined(USE_CACHEDB) && defined(USE_REDIS) + int port; + OUTYY(("P(redis_replica_server_port:%s)\n", (yyvsp[0].str))); + port = atoi((yyvsp[0].str)); + if(port == 0 || port < 0 || port > 65535) + yyerror("valid redis server port number expected"); + else cfg_parser->cfg->redis_replica_server_port = port; + #else + OUTYY(("P(Compiled without cachedb or redis, ignoring)\n")); + #endif + free((yyvsp[0].str)); + } +#line 7703 "util/configparser.c" break; - case 746: /* redis_server_path: VAR_CACHEDB_REDISPATH STRING_ARG */ -#line 3954 "util/configparser.y" + case 758: /* redis_server_path: VAR_CACHEDB_REDISPATH STRING_ARG */ +#line 4003 "util/configparser.y" { #if defined(USE_CACHEDB) && defined(USE_REDIS) OUTYY(("P(redis_server_path:%s)\n", (yyvsp[0].str))); @@ -7617,11 +7714,26 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 7621 "util/configparser.c" +#line 7718 "util/configparser.c" break; - case 747: /* redis_server_password: VAR_CACHEDB_REDISPASSWORD STRING_ARG */ -#line 3966 "util/configparser.y" + case 759: /* redis_replica_server_path: VAR_CACHEDB_REDISREPLICAPATH STRING_ARG */ +#line 4015 "util/configparser.y" + { + #if defined(USE_CACHEDB) && defined(USE_REDIS) + OUTYY(("P(redis_replica_server_path:%s)\n", (yyvsp[0].str))); + free(cfg_parser->cfg->redis_replica_server_path); + cfg_parser->cfg->redis_replica_server_path = (yyvsp[0].str); + #else + OUTYY(("P(Compiled without cachedb or redis, ignoring)\n")); + free((yyvsp[0].str)); + #endif + } +#line 7733 "util/configparser.c" + break; + + case 760: /* redis_server_password: VAR_CACHEDB_REDISPASSWORD STRING_ARG */ +#line 4027 "util/configparser.y" { #if defined(USE_CACHEDB) && defined(USE_REDIS) OUTYY(("P(redis_server_password:%s)\n", (yyvsp[0].str))); @@ -7632,11 +7744,26 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 7636 "util/configparser.c" +#line 7748 "util/configparser.c" + break; + + case 761: /* redis_replica_server_password: VAR_CACHEDB_REDISREPLICAPASSWORD STRING_ARG */ +#line 4039 "util/configparser.y" + { + #if defined(USE_CACHEDB) && defined(USE_REDIS) + OUTYY(("P(redis_replica_server_password:%s)\n", (yyvsp[0].str))); + free(cfg_parser->cfg->redis_replica_server_password); + cfg_parser->cfg->redis_replica_server_password = (yyvsp[0].str); + #else + OUTYY(("P(Compiled without cachedb or redis, ignoring)\n")); + free((yyvsp[0].str)); + #endif + } +#line 7763 "util/configparser.c" break; - case 748: /* redis_timeout: VAR_CACHEDB_REDISTIMEOUT STRING_ARG */ -#line 3978 "util/configparser.y" + case 762: /* redis_timeout: VAR_CACHEDB_REDISTIMEOUT STRING_ARG */ +#line 4051 "util/configparser.y" { #if defined(USE_CACHEDB) && defined(USE_REDIS) OUTYY(("P(redis_timeout:%s)\n", (yyvsp[0].str))); @@ -7648,11 +7775,27 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 7652 "util/configparser.c" +#line 7779 "util/configparser.c" + break; + + case 763: /* redis_replica_timeout: VAR_CACHEDB_REDISREPLICATIMEOUT STRING_ARG */ +#line 4064 "util/configparser.y" + { + #if defined(USE_CACHEDB) && defined(USE_REDIS) + OUTYY(("P(redis_replica_timeout:%s)\n", (yyvsp[0].str))); + if(atoi((yyvsp[0].str)) == 0) + yyerror("redis timeout value expected"); + else cfg_parser->cfg->redis_replica_timeout = atoi((yyvsp[0].str)); + #else + OUTYY(("P(Compiled without cachedb or redis, ignoring)\n")); + #endif + free((yyvsp[0].str)); + } +#line 7795 "util/configparser.c" break; - case 749: /* redis_command_timeout: VAR_CACHEDB_REDISCOMMANDTIMEOUT STRING_ARG */ -#line 3991 "util/configparser.y" + case 764: /* redis_command_timeout: VAR_CACHEDB_REDISCOMMANDTIMEOUT STRING_ARG */ +#line 4077 "util/configparser.y" { #if defined(USE_CACHEDB) && defined(USE_REDIS) OUTYY(("P(redis_command_timeout:%s)\n", (yyvsp[0].str))); @@ -7664,11 +7807,27 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 7668 "util/configparser.c" +#line 7811 "util/configparser.c" break; - case 750: /* redis_connect_timeout: VAR_CACHEDB_REDISCONNECTTIMEOUT STRING_ARG */ -#line 4004 "util/configparser.y" + case 765: /* redis_replica_command_timeout: VAR_CACHEDB_REDISREPLICACOMMANDTIMEOUT STRING_ARG */ +#line 4090 "util/configparser.y" + { + #if defined(USE_CACHEDB) && defined(USE_REDIS) + OUTYY(("P(redis_replica_command_timeout:%s)\n", (yyvsp[0].str))); + if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) + yyerror("redis command timeout value expected"); + else cfg_parser->cfg->redis_replica_command_timeout = atoi((yyvsp[0].str)); + #else + OUTYY(("P(Compiled without cachedb or redis, ignoring)\n")); + #endif + free((yyvsp[0].str)); + } +#line 7827 "util/configparser.c" + break; + + case 766: /* redis_connect_timeout: VAR_CACHEDB_REDISCONNECTTIMEOUT STRING_ARG */ +#line 4103 "util/configparser.y" { #if defined(USE_CACHEDB) && defined(USE_REDIS) OUTYY(("P(redis_connect_timeout:%s)\n", (yyvsp[0].str))); @@ -7680,11 +7839,27 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 7684 "util/configparser.c" +#line 7843 "util/configparser.c" break; - case 751: /* redis_expire_records: VAR_CACHEDB_REDISEXPIRERECORDS STRING_ARG */ -#line 4017 "util/configparser.y" + case 767: /* redis_replica_connect_timeout: VAR_CACHEDB_REDISREPLICACONNECTTIMEOUT STRING_ARG */ +#line 4116 "util/configparser.y" + { + #if defined(USE_CACHEDB) && defined(USE_REDIS) + OUTYY(("P(redis_replica_connect_timeout:%s)\n", (yyvsp[0].str))); + if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) + yyerror("redis connect timeout value expected"); + else cfg_parser->cfg->redis_replica_connect_timeout = atoi((yyvsp[0].str)); + #else + OUTYY(("P(Compiled without cachedb or redis, ignoring)\n")); + #endif + free((yyvsp[0].str)); + } +#line 7859 "util/configparser.c" + break; + + case 768: /* redis_expire_records: VAR_CACHEDB_REDISEXPIRERECORDS STRING_ARG */ +#line 4129 "util/configparser.y" { #if defined(USE_CACHEDB) && defined(USE_REDIS) OUTYY(("P(redis_expire_records:%s)\n", (yyvsp[0].str))); @@ -7696,11 +7871,11 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 7700 "util/configparser.c" +#line 7875 "util/configparser.c" break; - case 752: /* redis_logical_db: VAR_CACHEDB_REDISLOGICALDB STRING_ARG */ -#line 4030 "util/configparser.y" + case 769: /* redis_logical_db: VAR_CACHEDB_REDISLOGICALDB STRING_ARG */ +#line 4142 "util/configparser.y" { #if defined(USE_CACHEDB) && defined(USE_REDIS) int db; @@ -7714,11 +7889,29 @@ yyreduce: #endif free((yyvsp[0].str)); } -#line 7718 "util/configparser.c" +#line 7893 "util/configparser.c" + break; + + case 770: /* redis_replica_logical_db: VAR_CACHEDB_REDISREPLICALOGICALDB STRING_ARG */ +#line 4157 "util/configparser.y" + { + #if defined(USE_CACHEDB) && defined(USE_REDIS) + int db; + OUTYY(("P(redis_replica_logical_db:%s)\n", (yyvsp[0].str))); + db = atoi((yyvsp[0].str)); + if((db == 0 && strcmp((yyvsp[0].str), "0") != 0) || db < 0) + yyerror("valid redis logical database index expected"); + else cfg_parser->cfg->redis_replica_logical_db = db; + #else + OUTYY(("P(Compiled without cachedb or redis, ignoring)\n")); + #endif + free((yyvsp[0].str)); + } +#line 7911 "util/configparser.c" break; - case 753: /* server_tcp_connection_limit: VAR_TCP_CONNECTION_LIMIT STRING_ARG STRING_ARG */ -#line 4045 "util/configparser.y" + case 771: /* server_tcp_connection_limit: VAR_TCP_CONNECTION_LIMIT STRING_ARG STRING_ARG */ +#line 4172 "util/configparser.y" { OUTYY(("P(server_tcp_connection_limit:%s %s)\n", (yyvsp[-1].str), (yyvsp[0].str))); if (atoi((yyvsp[0].str)) < 0) @@ -7728,11 +7921,11 @@ yyreduce: fatal_exit("out of memory adding tcp connection limit"); } } -#line 7732 "util/configparser.c" +#line 7925 "util/configparser.c" break; - case 754: /* server_answer_cookie: VAR_ANSWER_COOKIE STRING_ARG */ -#line 4056 "util/configparser.y" + case 772: /* server_answer_cookie: VAR_ANSWER_COOKIE STRING_ARG */ +#line 4183 "util/configparser.y" { OUTYY(("P(server_answer_cookie:%s)\n", (yyvsp[0].str))); if(strcmp((yyvsp[0].str), "yes") != 0 && strcmp((yyvsp[0].str), "no") != 0) @@ -7740,11 +7933,11 @@ yyreduce: else cfg_parser->cfg->do_answer_cookie = (strcmp((yyvsp[0].str), "yes")==0); free((yyvsp[0].str)); } -#line 7744 "util/configparser.c" +#line 7937 "util/configparser.c" break; - case 755: /* server_cookie_secret: VAR_COOKIE_SECRET STRING_ARG */ -#line 4065 "util/configparser.y" + case 773: /* server_cookie_secret: VAR_COOKIE_SECRET STRING_ARG */ +#line 4192 "util/configparser.y" { uint8_t secret[32]; size_t secret_len = sizeof(secret); @@ -7759,21 +7952,21 @@ yyreduce: } free((yyvsp[0].str)); } -#line 7763 "util/configparser.c" +#line 7956 "util/configparser.c" break; - case 756: /* server_cookie_secret_file: VAR_COOKIE_SECRET_FILE STRING_ARG */ -#line 4081 "util/configparser.y" + case 774: /* server_cookie_secret_file: VAR_COOKIE_SECRET_FILE STRING_ARG */ +#line 4208 "util/configparser.y" { OUTYY(("P(cookie_secret_file:%s)\n", (yyvsp[0].str))); free(cfg_parser->cfg->cookie_secret_file); cfg_parser->cfg->cookie_secret_file = (yyvsp[0].str); } -#line 7773 "util/configparser.c" +#line 7966 "util/configparser.c" break; - case 757: /* server_iter_scrub_ns: VAR_ITER_SCRUB_NS STRING_ARG */ -#line 4088 "util/configparser.y" + case 775: /* server_iter_scrub_ns: VAR_ITER_SCRUB_NS STRING_ARG */ +#line 4215 "util/configparser.y" { OUTYY(("P(server_iter_scrub_ns:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -7781,11 +7974,11 @@ yyreduce: else cfg_parser->cfg->iter_scrub_ns = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 7785 "util/configparser.c" +#line 7978 "util/configparser.c" break; - case 758: /* server_iter_scrub_cname: VAR_ITER_SCRUB_CNAME STRING_ARG */ -#line 4097 "util/configparser.y" + case 776: /* server_iter_scrub_cname: VAR_ITER_SCRUB_CNAME STRING_ARG */ +#line 4224 "util/configparser.y" { OUTYY(("P(server_iter_scrub_cname:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -7793,11 +7986,11 @@ yyreduce: else cfg_parser->cfg->iter_scrub_cname = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 7797 "util/configparser.c" +#line 7990 "util/configparser.c" break; - case 759: /* server_max_global_quota: VAR_MAX_GLOBAL_QUOTA STRING_ARG */ -#line 4106 "util/configparser.y" + case 777: /* server_max_global_quota: VAR_MAX_GLOBAL_QUOTA STRING_ARG */ +#line 4233 "util/configparser.y" { OUTYY(("P(server_max_global_quota:%s)\n", (yyvsp[0].str))); if(atoi((yyvsp[0].str)) == 0 && strcmp((yyvsp[0].str), "0") != 0) @@ -7805,20 +7998,20 @@ yyreduce: else cfg_parser->cfg->max_global_quota = atoi((yyvsp[0].str)); free((yyvsp[0].str)); } -#line 7809 "util/configparser.c" +#line 8002 "util/configparser.c" break; - case 760: /* ipsetstart: VAR_IPSET */ -#line 4115 "util/configparser.y" + case 778: /* ipsetstart: VAR_IPSET */ +#line 4242 "util/configparser.y" { OUTYY(("\nP(ipset:)\n")); cfg_parser->started_toplevel = 1; } -#line 7818 "util/configparser.c" +#line 8011 "util/configparser.c" break; - case 765: /* ipset_name_v4: VAR_IPSET_NAME_V4 STRING_ARG */ -#line 4125 "util/configparser.y" + case 783: /* ipset_name_v4: VAR_IPSET_NAME_V4 STRING_ARG */ +#line 4252 "util/configparser.y" { #ifdef USE_IPSET OUTYY(("P(name-v4:%s)\n", (yyvsp[0].str))); @@ -7832,11 +8025,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 7836 "util/configparser.c" +#line 8029 "util/configparser.c" break; - case 766: /* ipset_name_v6: VAR_IPSET_NAME_V6 STRING_ARG */ -#line 4140 "util/configparser.y" + case 784: /* ipset_name_v6: VAR_IPSET_NAME_V6 STRING_ARG */ +#line 4267 "util/configparser.y" { #ifdef USE_IPSET OUTYY(("P(name-v6:%s)\n", (yyvsp[0].str))); @@ -7850,11 +8043,11 @@ yyreduce: free((yyvsp[0].str)); #endif } -#line 7854 "util/configparser.c" +#line 8047 "util/configparser.c" break; -#line 7858 "util/configparser.c" +#line 8051 "util/configparser.c" default: break; } @@ -8048,7 +8241,7 @@ yyreturn: return yyresult; } -#line 4154 "util/configparser.y" +#line 4281 "util/configparser.y" /* parse helper routines could be here */ diff --git a/util/configparser.h b/util/configparser.h index 8aa58d9ea49b..50ed20eef7a9 100644 --- a/util/configparser.h +++ b/util/configparser.h @@ -336,89 +336,98 @@ extern int yydebug; VAR_CACHEDB_BACKEND = 537, /* VAR_CACHEDB_BACKEND */ VAR_CACHEDB_SECRETSEED = 538, /* VAR_CACHEDB_SECRETSEED */ VAR_CACHEDB_REDISHOST = 539, /* VAR_CACHEDB_REDISHOST */ - VAR_CACHEDB_REDISPORT = 540, /* VAR_CACHEDB_REDISPORT */ - VAR_CACHEDB_REDISTIMEOUT = 541, /* VAR_CACHEDB_REDISTIMEOUT */ - VAR_CACHEDB_REDISEXPIRERECORDS = 542, /* VAR_CACHEDB_REDISEXPIRERECORDS */ - VAR_CACHEDB_REDISPATH = 543, /* VAR_CACHEDB_REDISPATH */ - VAR_CACHEDB_REDISPASSWORD = 544, /* VAR_CACHEDB_REDISPASSWORD */ - VAR_CACHEDB_REDISLOGICALDB = 545, /* VAR_CACHEDB_REDISLOGICALDB */ - VAR_CACHEDB_REDISCOMMANDTIMEOUT = 546, /* VAR_CACHEDB_REDISCOMMANDTIMEOUT */ - VAR_CACHEDB_REDISCONNECTTIMEOUT = 547, /* VAR_CACHEDB_REDISCONNECTTIMEOUT */ - VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 548, /* VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM */ - VAR_FOR_UPSTREAM = 549, /* VAR_FOR_UPSTREAM */ - VAR_AUTH_ZONE = 550, /* VAR_AUTH_ZONE */ - VAR_ZONEFILE = 551, /* VAR_ZONEFILE */ - VAR_MASTER = 552, /* VAR_MASTER */ - VAR_URL = 553, /* VAR_URL */ - VAR_FOR_DOWNSTREAM = 554, /* VAR_FOR_DOWNSTREAM */ - VAR_FALLBACK_ENABLED = 555, /* VAR_FALLBACK_ENABLED */ - VAR_TLS_ADDITIONAL_PORT = 556, /* VAR_TLS_ADDITIONAL_PORT */ - VAR_LOW_RTT = 557, /* VAR_LOW_RTT */ - VAR_LOW_RTT_PERMIL = 558, /* VAR_LOW_RTT_PERMIL */ - VAR_FAST_SERVER_PERMIL = 559, /* VAR_FAST_SERVER_PERMIL */ - VAR_FAST_SERVER_NUM = 560, /* VAR_FAST_SERVER_NUM */ - VAR_ALLOW_NOTIFY = 561, /* VAR_ALLOW_NOTIFY */ - VAR_TLS_WIN_CERT = 562, /* VAR_TLS_WIN_CERT */ - VAR_TCP_CONNECTION_LIMIT = 563, /* VAR_TCP_CONNECTION_LIMIT */ - VAR_ANSWER_COOKIE = 564, /* VAR_ANSWER_COOKIE */ - VAR_COOKIE_SECRET = 565, /* VAR_COOKIE_SECRET */ - VAR_IP_RATELIMIT_COOKIE = 566, /* VAR_IP_RATELIMIT_COOKIE */ - VAR_FORWARD_NO_CACHE = 567, /* VAR_FORWARD_NO_CACHE */ - VAR_STUB_NO_CACHE = 568, /* VAR_STUB_NO_CACHE */ - VAR_LOG_SERVFAIL = 569, /* VAR_LOG_SERVFAIL */ - VAR_DENY_ANY = 570, /* VAR_DENY_ANY */ - VAR_UNKNOWN_SERVER_TIME_LIMIT = 571, /* VAR_UNKNOWN_SERVER_TIME_LIMIT */ - VAR_LOG_TAG_QUERYREPLY = 572, /* VAR_LOG_TAG_QUERYREPLY */ - VAR_DISCARD_TIMEOUT = 573, /* VAR_DISCARD_TIMEOUT */ - VAR_WAIT_LIMIT = 574, /* VAR_WAIT_LIMIT */ - VAR_WAIT_LIMIT_COOKIE = 575, /* VAR_WAIT_LIMIT_COOKIE */ - VAR_WAIT_LIMIT_NETBLOCK = 576, /* VAR_WAIT_LIMIT_NETBLOCK */ - VAR_WAIT_LIMIT_COOKIE_NETBLOCK = 577, /* VAR_WAIT_LIMIT_COOKIE_NETBLOCK */ - VAR_STREAM_WAIT_SIZE = 578, /* VAR_STREAM_WAIT_SIZE */ - VAR_TLS_CIPHERS = 579, /* VAR_TLS_CIPHERS */ - VAR_TLS_CIPHERSUITES = 580, /* VAR_TLS_CIPHERSUITES */ - VAR_TLS_USE_SNI = 581, /* VAR_TLS_USE_SNI */ - VAR_IPSET = 582, /* VAR_IPSET */ - VAR_IPSET_NAME_V4 = 583, /* VAR_IPSET_NAME_V4 */ - VAR_IPSET_NAME_V6 = 584, /* VAR_IPSET_NAME_V6 */ - VAR_TLS_SESSION_TICKET_KEYS = 585, /* VAR_TLS_SESSION_TICKET_KEYS */ - VAR_RPZ = 586, /* VAR_RPZ */ - VAR_TAGS = 587, /* VAR_TAGS */ - VAR_RPZ_ACTION_OVERRIDE = 588, /* VAR_RPZ_ACTION_OVERRIDE */ - VAR_RPZ_CNAME_OVERRIDE = 589, /* VAR_RPZ_CNAME_OVERRIDE */ - VAR_RPZ_LOG = 590, /* VAR_RPZ_LOG */ - VAR_RPZ_LOG_NAME = 591, /* VAR_RPZ_LOG_NAME */ - VAR_DYNLIB = 592, /* VAR_DYNLIB */ - VAR_DYNLIB_FILE = 593, /* VAR_DYNLIB_FILE */ - VAR_EDNS_CLIENT_STRING = 594, /* VAR_EDNS_CLIENT_STRING */ - VAR_EDNS_CLIENT_STRING_OPCODE = 595, /* VAR_EDNS_CLIENT_STRING_OPCODE */ - VAR_NSID = 596, /* VAR_NSID */ - VAR_ZONEMD_PERMISSIVE_MODE = 597, /* VAR_ZONEMD_PERMISSIVE_MODE */ - VAR_ZONEMD_CHECK = 598, /* VAR_ZONEMD_CHECK */ - VAR_ZONEMD_REJECT_ABSENCE = 599, /* VAR_ZONEMD_REJECT_ABSENCE */ - VAR_RPZ_SIGNAL_NXDOMAIN_RA = 600, /* VAR_RPZ_SIGNAL_NXDOMAIN_RA */ - VAR_INTERFACE_AUTOMATIC_PORTS = 601, /* VAR_INTERFACE_AUTOMATIC_PORTS */ - VAR_EDE = 602, /* VAR_EDE */ - VAR_INTERFACE_ACTION = 603, /* VAR_INTERFACE_ACTION */ - VAR_INTERFACE_VIEW = 604, /* VAR_INTERFACE_VIEW */ - VAR_INTERFACE_TAG = 605, /* VAR_INTERFACE_TAG */ - VAR_INTERFACE_TAG_ACTION = 606, /* VAR_INTERFACE_TAG_ACTION */ - VAR_INTERFACE_TAG_DATA = 607, /* VAR_INTERFACE_TAG_DATA */ - VAR_QUIC_PORT = 608, /* VAR_QUIC_PORT */ - VAR_QUIC_SIZE = 609, /* VAR_QUIC_SIZE */ - VAR_PROXY_PROTOCOL_PORT = 610, /* VAR_PROXY_PROTOCOL_PORT */ - VAR_STATISTICS_INHIBIT_ZERO = 611, /* VAR_STATISTICS_INHIBIT_ZERO */ - VAR_HARDEN_UNKNOWN_ADDITIONAL = 612, /* VAR_HARDEN_UNKNOWN_ADDITIONAL */ - VAR_DISABLE_EDNS_DO = 613, /* VAR_DISABLE_EDNS_DO */ - VAR_CACHEDB_NO_STORE = 614, /* VAR_CACHEDB_NO_STORE */ - VAR_LOG_DESTADDR = 615, /* VAR_LOG_DESTADDR */ - VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED = 616, /* VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED */ - VAR_COOKIE_SECRET_FILE = 617, /* VAR_COOKIE_SECRET_FILE */ - VAR_ITER_SCRUB_NS = 618, /* VAR_ITER_SCRUB_NS */ - VAR_ITER_SCRUB_CNAME = 619, /* VAR_ITER_SCRUB_CNAME */ - VAR_MAX_GLOBAL_QUOTA = 620, /* VAR_MAX_GLOBAL_QUOTA */ - VAR_HARDEN_UNVERIFIED_GLUE = 621, /* VAR_HARDEN_UNVERIFIED_GLUE */ - VAR_LOG_TIME_ISO = 622 /* VAR_LOG_TIME_ISO */ + VAR_CACHEDB_REDISREPLICAHOST = 540, /* VAR_CACHEDB_REDISREPLICAHOST */ + VAR_CACHEDB_REDISPORT = 541, /* VAR_CACHEDB_REDISPORT */ + VAR_CACHEDB_REDISREPLICAPORT = 542, /* VAR_CACHEDB_REDISREPLICAPORT */ + VAR_CACHEDB_REDISTIMEOUT = 543, /* VAR_CACHEDB_REDISTIMEOUT */ + VAR_CACHEDB_REDISREPLICATIMEOUT = 544, /* VAR_CACHEDB_REDISREPLICATIMEOUT */ + VAR_CACHEDB_REDISEXPIRERECORDS = 545, /* VAR_CACHEDB_REDISEXPIRERECORDS */ + VAR_CACHEDB_REDISPATH = 546, /* VAR_CACHEDB_REDISPATH */ + VAR_CACHEDB_REDISREPLICAPATH = 547, /* VAR_CACHEDB_REDISREPLICAPATH */ + VAR_CACHEDB_REDISPASSWORD = 548, /* VAR_CACHEDB_REDISPASSWORD */ + VAR_CACHEDB_REDISREPLICAPASSWORD = 549, /* VAR_CACHEDB_REDISREPLICAPASSWORD */ + VAR_CACHEDB_REDISLOGICALDB = 550, /* VAR_CACHEDB_REDISLOGICALDB */ + VAR_CACHEDB_REDISREPLICALOGICALDB = 551, /* VAR_CACHEDB_REDISREPLICALOGICALDB */ + VAR_CACHEDB_REDISCOMMANDTIMEOUT = 552, /* VAR_CACHEDB_REDISCOMMANDTIMEOUT */ + VAR_CACHEDB_REDISREPLICACOMMANDTIMEOUT = 553, /* VAR_CACHEDB_REDISREPLICACOMMANDTIMEOUT */ + VAR_CACHEDB_REDISCONNECTTIMEOUT = 554, /* VAR_CACHEDB_REDISCONNECTTIMEOUT */ + VAR_CACHEDB_REDISREPLICACONNECTTIMEOUT = 555, /* VAR_CACHEDB_REDISREPLICACONNECTTIMEOUT */ + VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 556, /* VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM */ + VAR_FOR_UPSTREAM = 557, /* VAR_FOR_UPSTREAM */ + VAR_AUTH_ZONE = 558, /* VAR_AUTH_ZONE */ + VAR_ZONEFILE = 559, /* VAR_ZONEFILE */ + VAR_MASTER = 560, /* VAR_MASTER */ + VAR_URL = 561, /* VAR_URL */ + VAR_FOR_DOWNSTREAM = 562, /* VAR_FOR_DOWNSTREAM */ + VAR_FALLBACK_ENABLED = 563, /* VAR_FALLBACK_ENABLED */ + VAR_TLS_ADDITIONAL_PORT = 564, /* VAR_TLS_ADDITIONAL_PORT */ + VAR_LOW_RTT = 565, /* VAR_LOW_RTT */ + VAR_LOW_RTT_PERMIL = 566, /* VAR_LOW_RTT_PERMIL */ + VAR_FAST_SERVER_PERMIL = 567, /* VAR_FAST_SERVER_PERMIL */ + VAR_FAST_SERVER_NUM = 568, /* VAR_FAST_SERVER_NUM */ + VAR_ALLOW_NOTIFY = 569, /* VAR_ALLOW_NOTIFY */ + VAR_TLS_WIN_CERT = 570, /* VAR_TLS_WIN_CERT */ + VAR_TCP_CONNECTION_LIMIT = 571, /* VAR_TCP_CONNECTION_LIMIT */ + VAR_ANSWER_COOKIE = 572, /* VAR_ANSWER_COOKIE */ + VAR_COOKIE_SECRET = 573, /* VAR_COOKIE_SECRET */ + VAR_IP_RATELIMIT_COOKIE = 574, /* VAR_IP_RATELIMIT_COOKIE */ + VAR_FORWARD_NO_CACHE = 575, /* VAR_FORWARD_NO_CACHE */ + VAR_STUB_NO_CACHE = 576, /* VAR_STUB_NO_CACHE */ + VAR_LOG_SERVFAIL = 577, /* VAR_LOG_SERVFAIL */ + VAR_DENY_ANY = 578, /* VAR_DENY_ANY */ + VAR_UNKNOWN_SERVER_TIME_LIMIT = 579, /* VAR_UNKNOWN_SERVER_TIME_LIMIT */ + VAR_LOG_TAG_QUERYREPLY = 580, /* VAR_LOG_TAG_QUERYREPLY */ + VAR_DISCARD_TIMEOUT = 581, /* VAR_DISCARD_TIMEOUT */ + VAR_WAIT_LIMIT = 582, /* VAR_WAIT_LIMIT */ + VAR_WAIT_LIMIT_COOKIE = 583, /* VAR_WAIT_LIMIT_COOKIE */ + VAR_WAIT_LIMIT_NETBLOCK = 584, /* VAR_WAIT_LIMIT_NETBLOCK */ + VAR_WAIT_LIMIT_COOKIE_NETBLOCK = 585, /* VAR_WAIT_LIMIT_COOKIE_NETBLOCK */ + VAR_STREAM_WAIT_SIZE = 586, /* VAR_STREAM_WAIT_SIZE */ + VAR_TLS_CIPHERS = 587, /* VAR_TLS_CIPHERS */ + VAR_TLS_CIPHERSUITES = 588, /* VAR_TLS_CIPHERSUITES */ + VAR_TLS_USE_SNI = 589, /* VAR_TLS_USE_SNI */ + VAR_IPSET = 590, /* VAR_IPSET */ + VAR_IPSET_NAME_V4 = 591, /* VAR_IPSET_NAME_V4 */ + VAR_IPSET_NAME_V6 = 592, /* VAR_IPSET_NAME_V6 */ + VAR_TLS_SESSION_TICKET_KEYS = 593, /* VAR_TLS_SESSION_TICKET_KEYS */ + VAR_RPZ = 594, /* VAR_RPZ */ + VAR_TAGS = 595, /* VAR_TAGS */ + VAR_RPZ_ACTION_OVERRIDE = 596, /* VAR_RPZ_ACTION_OVERRIDE */ + VAR_RPZ_CNAME_OVERRIDE = 597, /* VAR_RPZ_CNAME_OVERRIDE */ + VAR_RPZ_LOG = 598, /* VAR_RPZ_LOG */ + VAR_RPZ_LOG_NAME = 599, /* VAR_RPZ_LOG_NAME */ + VAR_DYNLIB = 600, /* VAR_DYNLIB */ + VAR_DYNLIB_FILE = 601, /* VAR_DYNLIB_FILE */ + VAR_EDNS_CLIENT_STRING = 602, /* VAR_EDNS_CLIENT_STRING */ + VAR_EDNS_CLIENT_STRING_OPCODE = 603, /* VAR_EDNS_CLIENT_STRING_OPCODE */ + VAR_NSID = 604, /* VAR_NSID */ + VAR_ZONEMD_PERMISSIVE_MODE = 605, /* VAR_ZONEMD_PERMISSIVE_MODE */ + VAR_ZONEMD_CHECK = 606, /* VAR_ZONEMD_CHECK */ + VAR_ZONEMD_REJECT_ABSENCE = 607, /* VAR_ZONEMD_REJECT_ABSENCE */ + VAR_RPZ_SIGNAL_NXDOMAIN_RA = 608, /* VAR_RPZ_SIGNAL_NXDOMAIN_RA */ + VAR_INTERFACE_AUTOMATIC_PORTS = 609, /* VAR_INTERFACE_AUTOMATIC_PORTS */ + VAR_EDE = 610, /* VAR_EDE */ + VAR_DNS_ERROR_REPORTING = 611, /* VAR_DNS_ERROR_REPORTING */ + VAR_INTERFACE_ACTION = 612, /* VAR_INTERFACE_ACTION */ + VAR_INTERFACE_VIEW = 613, /* VAR_INTERFACE_VIEW */ + VAR_INTERFACE_TAG = 614, /* VAR_INTERFACE_TAG */ + VAR_INTERFACE_TAG_ACTION = 615, /* VAR_INTERFACE_TAG_ACTION */ + VAR_INTERFACE_TAG_DATA = 616, /* VAR_INTERFACE_TAG_DATA */ + VAR_QUIC_PORT = 617, /* VAR_QUIC_PORT */ + VAR_QUIC_SIZE = 618, /* VAR_QUIC_SIZE */ + VAR_PROXY_PROTOCOL_PORT = 619, /* VAR_PROXY_PROTOCOL_PORT */ + VAR_STATISTICS_INHIBIT_ZERO = 620, /* VAR_STATISTICS_INHIBIT_ZERO */ + VAR_HARDEN_UNKNOWN_ADDITIONAL = 621, /* VAR_HARDEN_UNKNOWN_ADDITIONAL */ + VAR_DISABLE_EDNS_DO = 622, /* VAR_DISABLE_EDNS_DO */ + VAR_CACHEDB_NO_STORE = 623, /* VAR_CACHEDB_NO_STORE */ + VAR_LOG_DESTADDR = 624, /* VAR_LOG_DESTADDR */ + VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED = 625, /* VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED */ + VAR_COOKIE_SECRET_FILE = 626, /* VAR_COOKIE_SECRET_FILE */ + VAR_ITER_SCRUB_NS = 627, /* VAR_ITER_SCRUB_NS */ + VAR_ITER_SCRUB_CNAME = 628, /* VAR_ITER_SCRUB_CNAME */ + VAR_MAX_GLOBAL_QUOTA = 629, /* VAR_MAX_GLOBAL_QUOTA */ + VAR_HARDEN_UNVERIFIED_GLUE = 630, /* VAR_HARDEN_UNVERIFIED_GLUE */ + VAR_LOG_TIME_ISO = 631 /* VAR_LOG_TIME_ISO */ }; typedef enum yytokentype yytoken_kind_t; #endif @@ -709,89 +718,98 @@ extern int yydebug; #define VAR_CACHEDB_BACKEND 537 #define VAR_CACHEDB_SECRETSEED 538 #define VAR_CACHEDB_REDISHOST 539 -#define VAR_CACHEDB_REDISPORT 540 -#define VAR_CACHEDB_REDISTIMEOUT 541 -#define VAR_CACHEDB_REDISEXPIRERECORDS 542 -#define VAR_CACHEDB_REDISPATH 543 -#define VAR_CACHEDB_REDISPASSWORD 544 -#define VAR_CACHEDB_REDISLOGICALDB 545 -#define VAR_CACHEDB_REDISCOMMANDTIMEOUT 546 -#define VAR_CACHEDB_REDISCONNECTTIMEOUT 547 -#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 548 -#define VAR_FOR_UPSTREAM 549 -#define VAR_AUTH_ZONE 550 -#define VAR_ZONEFILE 551 -#define VAR_MASTER 552 -#define VAR_URL 553 -#define VAR_FOR_DOWNSTREAM 554 -#define VAR_FALLBACK_ENABLED 555 -#define VAR_TLS_ADDITIONAL_PORT 556 -#define VAR_LOW_RTT 557 -#define VAR_LOW_RTT_PERMIL 558 -#define VAR_FAST_SERVER_PERMIL 559 -#define VAR_FAST_SERVER_NUM 560 -#define VAR_ALLOW_NOTIFY 561 -#define VAR_TLS_WIN_CERT 562 -#define VAR_TCP_CONNECTION_LIMIT 563 -#define VAR_ANSWER_COOKIE 564 -#define VAR_COOKIE_SECRET 565 -#define VAR_IP_RATELIMIT_COOKIE 566 -#define VAR_FORWARD_NO_CACHE 567 -#define VAR_STUB_NO_CACHE 568 -#define VAR_LOG_SERVFAIL 569 -#define VAR_DENY_ANY 570 -#define VAR_UNKNOWN_SERVER_TIME_LIMIT 571 -#define VAR_LOG_TAG_QUERYREPLY 572 -#define VAR_DISCARD_TIMEOUT 573 -#define VAR_WAIT_LIMIT 574 -#define VAR_WAIT_LIMIT_COOKIE 575 -#define VAR_WAIT_LIMIT_NETBLOCK 576 -#define VAR_WAIT_LIMIT_COOKIE_NETBLOCK 577 -#define VAR_STREAM_WAIT_SIZE 578 -#define VAR_TLS_CIPHERS 579 -#define VAR_TLS_CIPHERSUITES 580 -#define VAR_TLS_USE_SNI 581 -#define VAR_IPSET 582 -#define VAR_IPSET_NAME_V4 583 -#define VAR_IPSET_NAME_V6 584 -#define VAR_TLS_SESSION_TICKET_KEYS 585 -#define VAR_RPZ 586 -#define VAR_TAGS 587 -#define VAR_RPZ_ACTION_OVERRIDE 588 -#define VAR_RPZ_CNAME_OVERRIDE 589 -#define VAR_RPZ_LOG 590 -#define VAR_RPZ_LOG_NAME 591 -#define VAR_DYNLIB 592 -#define VAR_DYNLIB_FILE 593 -#define VAR_EDNS_CLIENT_STRING 594 -#define VAR_EDNS_CLIENT_STRING_OPCODE 595 -#define VAR_NSID 596 -#define VAR_ZONEMD_PERMISSIVE_MODE 597 -#define VAR_ZONEMD_CHECK 598 -#define VAR_ZONEMD_REJECT_ABSENCE 599 -#define VAR_RPZ_SIGNAL_NXDOMAIN_RA 600 -#define VAR_INTERFACE_AUTOMATIC_PORTS 601 -#define VAR_EDE 602 -#define VAR_INTERFACE_ACTION 603 -#define VAR_INTERFACE_VIEW 604 -#define VAR_INTERFACE_TAG 605 -#define VAR_INTERFACE_TAG_ACTION 606 -#define VAR_INTERFACE_TAG_DATA 607 -#define VAR_QUIC_PORT 608 -#define VAR_QUIC_SIZE 609 -#define VAR_PROXY_PROTOCOL_PORT 610 -#define VAR_STATISTICS_INHIBIT_ZERO 611 -#define VAR_HARDEN_UNKNOWN_ADDITIONAL 612 -#define VAR_DISABLE_EDNS_DO 613 -#define VAR_CACHEDB_NO_STORE 614 -#define VAR_LOG_DESTADDR 615 -#define VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED 616 -#define VAR_COOKIE_SECRET_FILE 617 -#define VAR_ITER_SCRUB_NS 618 -#define VAR_ITER_SCRUB_CNAME 619 -#define VAR_MAX_GLOBAL_QUOTA 620 -#define VAR_HARDEN_UNVERIFIED_GLUE 621 -#define VAR_LOG_TIME_ISO 622 +#define VAR_CACHEDB_REDISREPLICAHOST 540 +#define VAR_CACHEDB_REDISPORT 541 +#define VAR_CACHEDB_REDISREPLICAPORT 542 +#define VAR_CACHEDB_REDISTIMEOUT 543 +#define VAR_CACHEDB_REDISREPLICATIMEOUT 544 +#define VAR_CACHEDB_REDISEXPIRERECORDS 545 +#define VAR_CACHEDB_REDISPATH 546 +#define VAR_CACHEDB_REDISREPLICAPATH 547 +#define VAR_CACHEDB_REDISPASSWORD 548 +#define VAR_CACHEDB_REDISREPLICAPASSWORD 549 +#define VAR_CACHEDB_REDISLOGICALDB 550 +#define VAR_CACHEDB_REDISREPLICALOGICALDB 551 +#define VAR_CACHEDB_REDISCOMMANDTIMEOUT 552 +#define VAR_CACHEDB_REDISREPLICACOMMANDTIMEOUT 553 +#define VAR_CACHEDB_REDISCONNECTTIMEOUT 554 +#define VAR_CACHEDB_REDISREPLICACONNECTTIMEOUT 555 +#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 556 +#define VAR_FOR_UPSTREAM 557 +#define VAR_AUTH_ZONE 558 +#define VAR_ZONEFILE 559 +#define VAR_MASTER 560 +#define VAR_URL 561 +#define VAR_FOR_DOWNSTREAM 562 +#define VAR_FALLBACK_ENABLED 563 +#define VAR_TLS_ADDITIONAL_PORT 564 +#define VAR_LOW_RTT 565 +#define VAR_LOW_RTT_PERMIL 566 +#define VAR_FAST_SERVER_PERMIL 567 +#define VAR_FAST_SERVER_NUM 568 +#define VAR_ALLOW_NOTIFY 569 +#define VAR_TLS_WIN_CERT 570 +#define VAR_TCP_CONNECTION_LIMIT 571 +#define VAR_ANSWER_COOKIE 572 +#define VAR_COOKIE_SECRET 573 +#define VAR_IP_RATELIMIT_COOKIE 574 +#define VAR_FORWARD_NO_CACHE 575 +#define VAR_STUB_NO_CACHE 576 +#define VAR_LOG_SERVFAIL 577 +#define VAR_DENY_ANY 578 +#define VAR_UNKNOWN_SERVER_TIME_LIMIT 579 +#define VAR_LOG_TAG_QUERYREPLY 580 +#define VAR_DISCARD_TIMEOUT 581 +#define VAR_WAIT_LIMIT 582 +#define VAR_WAIT_LIMIT_COOKIE 583 +#define VAR_WAIT_LIMIT_NETBLOCK 584 +#define VAR_WAIT_LIMIT_COOKIE_NETBLOCK 585 +#define VAR_STREAM_WAIT_SIZE 586 +#define VAR_TLS_CIPHERS 587 +#define VAR_TLS_CIPHERSUITES 588 +#define VAR_TLS_USE_SNI 589 +#define VAR_IPSET 590 +#define VAR_IPSET_NAME_V4 591 +#define VAR_IPSET_NAME_V6 592 +#define VAR_TLS_SESSION_TICKET_KEYS 593 +#define VAR_RPZ 594 +#define VAR_TAGS 595 +#define VAR_RPZ_ACTION_OVERRIDE 596 +#define VAR_RPZ_CNAME_OVERRIDE 597 +#define VAR_RPZ_LOG 598 +#define VAR_RPZ_LOG_NAME 599 +#define VAR_DYNLIB 600 +#define VAR_DYNLIB_FILE 601 +#define VAR_EDNS_CLIENT_STRING 602 +#define VAR_EDNS_CLIENT_STRING_OPCODE 603 +#define VAR_NSID 604 +#define VAR_ZONEMD_PERMISSIVE_MODE 605 +#define VAR_ZONEMD_CHECK 606 +#define VAR_ZONEMD_REJECT_ABSENCE 607 +#define VAR_RPZ_SIGNAL_NXDOMAIN_RA 608 +#define VAR_INTERFACE_AUTOMATIC_PORTS 609 +#define VAR_EDE 610 +#define VAR_DNS_ERROR_REPORTING 611 +#define VAR_INTERFACE_ACTION 612 +#define VAR_INTERFACE_VIEW 613 +#define VAR_INTERFACE_TAG 614 +#define VAR_INTERFACE_TAG_ACTION 615 +#define VAR_INTERFACE_TAG_DATA 616 +#define VAR_QUIC_PORT 617 +#define VAR_QUIC_SIZE 618 +#define VAR_PROXY_PROTOCOL_PORT 619 +#define VAR_STATISTICS_INHIBIT_ZERO 620 +#define VAR_HARDEN_UNKNOWN_ADDITIONAL 621 +#define VAR_DISABLE_EDNS_DO 622 +#define VAR_CACHEDB_NO_STORE 623 +#define VAR_LOG_DESTADDR 624 +#define VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED 625 +#define VAR_COOKIE_SECRET_FILE 626 +#define VAR_ITER_SCRUB_NS 627 +#define VAR_ITER_SCRUB_CNAME 628 +#define VAR_MAX_GLOBAL_QUOTA 629 +#define VAR_HARDEN_UNVERIFIED_GLUE 630 +#define VAR_LOG_TIME_ISO 631 /* Value type. */ #if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED @@ -801,7 +819,7 @@ union YYSTYPE char* str; -#line 805 "util/configparser.h" +#line 823 "util/configparser.h" }; typedef union YYSTYPE YYSTYPE; diff --git a/util/configparser.y b/util/configparser.y index c10a5f475d32..ebb23f41cbd3 100644 --- a/util/configparser.y +++ b/util/configparser.y @@ -179,10 +179,15 @@ extern struct config_parser_state* cfg_parser; %token VAR_IPSECMOD_ENABLED VAR_IPSECMOD_HOOK VAR_IPSECMOD_IGNORE_BOGUS %token VAR_IPSECMOD_MAX_TTL VAR_IPSECMOD_WHITELIST VAR_IPSECMOD_STRICT %token VAR_CACHEDB VAR_CACHEDB_BACKEND VAR_CACHEDB_SECRETSEED -%token VAR_CACHEDB_REDISHOST VAR_CACHEDB_REDISPORT VAR_CACHEDB_REDISTIMEOUT -%token VAR_CACHEDB_REDISEXPIRERECORDS VAR_CACHEDB_REDISPATH VAR_CACHEDB_REDISPASSWORD -%token VAR_CACHEDB_REDISLOGICALDB -%token VAR_CACHEDB_REDISCOMMANDTIMEOUT VAR_CACHEDB_REDISCONNECTTIMEOUT +%token VAR_CACHEDB_REDISHOST VAR_CACHEDB_REDISREPLICAHOST +%token VAR_CACHEDB_REDISPORT VAR_CACHEDB_REDISREPLICAPORT +%token VAR_CACHEDB_REDISTIMEOUT VAR_CACHEDB_REDISREPLICATIMEOUT +%token VAR_CACHEDB_REDISEXPIRERECORDS +%token VAR_CACHEDB_REDISPATH VAR_CACHEDB_REDISREPLICAPATH +%token VAR_CACHEDB_REDISPASSWORD VAR_CACHEDB_REDISREPLICAPASSWORD +%token VAR_CACHEDB_REDISLOGICALDB VAR_CACHEDB_REDISREPLICALOGICALDB +%token VAR_CACHEDB_REDISCOMMANDTIMEOUT VAR_CACHEDB_REDISREPLICACOMMANDTIMEOUT +%token VAR_CACHEDB_REDISCONNECTTIMEOUT VAR_CACHEDB_REDISREPLICACONNECTTIMEOUT %token VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM VAR_FOR_UPSTREAM %token VAR_AUTH_ZONE VAR_ZONEFILE VAR_MASTER VAR_URL VAR_FOR_DOWNSTREAM %token VAR_FALLBACK_ENABLED VAR_TLS_ADDITIONAL_PORT VAR_LOW_RTT VAR_LOW_RTT_PERMIL @@ -201,6 +206,7 @@ extern struct config_parser_state* cfg_parser; %token VAR_EDNS_CLIENT_STRING_OPCODE VAR_NSID %token VAR_ZONEMD_PERMISSIVE_MODE VAR_ZONEMD_CHECK VAR_ZONEMD_REJECT_ABSENCE %token VAR_RPZ_SIGNAL_NXDOMAIN_RA VAR_INTERFACE_AUTOMATIC_PORTS VAR_EDE +%token VAR_DNS_ERROR_REPORTING %token VAR_INTERFACE_ACTION VAR_INTERFACE_VIEW VAR_INTERFACE_TAG %token VAR_INTERFACE_TAG_ACTION VAR_INTERFACE_TAG_DATA %token VAR_QUIC_PORT VAR_QUIC_SIZE @@ -345,6 +351,7 @@ content_server: server_num_threads | server_verbosity | server_port | server_tcp_reuse_timeout | server_tcp_auth_query_timeout | server_quic_port | server_quic_size | server_interface_automatic_ports | server_ede | + server_dns_error_reporting | server_proxy_protocol_port | server_statistics_inhibit_zero | server_harden_unknown_additional | server_disable_edns_do | server_log_destaddr | server_cookie_secret_file | @@ -3068,6 +3075,15 @@ server_ede: VAR_EDE STRING_ARG free($2); } ; +server_dns_error_reporting: VAR_DNS_ERROR_REPORTING STRING_ARG + { + OUTYY(("P(server_dns_error_reporting:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->dns_error_reporting = (strcmp($2, "yes")==0); + free($2); + } + ; server_proxy_protocol_port: VAR_PROXY_PROTOCOL_PORT STRING_ARG { OUTYY(("P(server_proxy_protocol_port:%s)\n", $2)); @@ -3868,10 +3884,16 @@ cachedbstart: VAR_CACHEDB contents_cachedb: contents_cachedb content_cachedb | ; content_cachedb: cachedb_backend_name | cachedb_secret_seed | - redis_server_host | redis_server_port | redis_timeout | - redis_expire_records | redis_server_path | redis_server_password | - cachedb_no_store | redis_logical_db | cachedb_check_when_serve_expired | - redis_command_timeout | redis_connect_timeout + redis_server_host | redis_replica_server_host | + redis_server_port | redis_replica_server_port | + redis_timeout | redis_replica_timeout | + redis_command_timeout | redis_replica_command_timeout | + redis_connect_timeout | redis_replica_connect_timeout | + redis_server_path | redis_replica_server_path | + redis_server_password | redis_replica_server_password | + redis_logical_db | redis_replica_logical_db | + cachedb_no_store | redis_expire_records | + cachedb_check_when_serve_expired ; cachedb_backend_name: VAR_CACHEDB_BACKEND STRING_ARG { @@ -3935,6 +3957,18 @@ redis_server_host: VAR_CACHEDB_REDISHOST STRING_ARG #endif } ; +redis_replica_server_host: VAR_CACHEDB_REDISREPLICAHOST STRING_ARG + { + #if defined(USE_CACHEDB) && defined(USE_REDIS) + OUTYY(("P(redis_replica_server_host:%s)\n", $2)); + free(cfg_parser->cfg->redis_replica_server_host); + cfg_parser->cfg->redis_replica_server_host = $2; + #else + OUTYY(("P(Compiled without cachedb or redis, ignoring)\n")); + free($2); + #endif + } + ; redis_server_port: VAR_CACHEDB_REDISPORT STRING_ARG { #if defined(USE_CACHEDB) && defined(USE_REDIS) @@ -3950,6 +3984,21 @@ redis_server_port: VAR_CACHEDB_REDISPORT STRING_ARG free($2); } ; +redis_replica_server_port: VAR_CACHEDB_REDISREPLICAPORT STRING_ARG + { + #if defined(USE_CACHEDB) && defined(USE_REDIS) + int port; + OUTYY(("P(redis_replica_server_port:%s)\n", $2)); + port = atoi($2); + if(port == 0 || port < 0 || port > 65535) + yyerror("valid redis server port number expected"); + else cfg_parser->cfg->redis_replica_server_port = port; + #else + OUTYY(("P(Compiled without cachedb or redis, ignoring)\n")); + #endif + free($2); + } + ; redis_server_path: VAR_CACHEDB_REDISPATH STRING_ARG { #if defined(USE_CACHEDB) && defined(USE_REDIS) @@ -3962,6 +4011,18 @@ redis_server_path: VAR_CACHEDB_REDISPATH STRING_ARG #endif } ; +redis_replica_server_path: VAR_CACHEDB_REDISREPLICAPATH STRING_ARG + { + #if defined(USE_CACHEDB) && defined(USE_REDIS) + OUTYY(("P(redis_replica_server_path:%s)\n", $2)); + free(cfg_parser->cfg->redis_replica_server_path); + cfg_parser->cfg->redis_replica_server_path = $2; + #else + OUTYY(("P(Compiled without cachedb or redis, ignoring)\n")); + free($2); + #endif + } + ; redis_server_password: VAR_CACHEDB_REDISPASSWORD STRING_ARG { #if defined(USE_CACHEDB) && defined(USE_REDIS) @@ -3974,6 +4035,18 @@ redis_server_password: VAR_CACHEDB_REDISPASSWORD STRING_ARG #endif } ; +redis_replica_server_password: VAR_CACHEDB_REDISREPLICAPASSWORD STRING_ARG + { + #if defined(USE_CACHEDB) && defined(USE_REDIS) + OUTYY(("P(redis_replica_server_password:%s)\n", $2)); + free(cfg_parser->cfg->redis_replica_server_password); + cfg_parser->cfg->redis_replica_server_password = $2; + #else + OUTYY(("P(Compiled without cachedb or redis, ignoring)\n")); + free($2); + #endif + } + ; redis_timeout: VAR_CACHEDB_REDISTIMEOUT STRING_ARG { #if defined(USE_CACHEDB) && defined(USE_REDIS) @@ -3987,6 +4060,19 @@ redis_timeout: VAR_CACHEDB_REDISTIMEOUT STRING_ARG free($2); } ; +redis_replica_timeout: VAR_CACHEDB_REDISREPLICATIMEOUT STRING_ARG + { + #if defined(USE_CACHEDB) && defined(USE_REDIS) + OUTYY(("P(redis_replica_timeout:%s)\n", $2)); + if(atoi($2) == 0) + yyerror("redis timeout value expected"); + else cfg_parser->cfg->redis_replica_timeout = atoi($2); + #else + OUTYY(("P(Compiled without cachedb or redis, ignoring)\n")); + #endif + free($2); + } + ; redis_command_timeout: VAR_CACHEDB_REDISCOMMANDTIMEOUT STRING_ARG { #if defined(USE_CACHEDB) && defined(USE_REDIS) @@ -4000,6 +4086,19 @@ redis_command_timeout: VAR_CACHEDB_REDISCOMMANDTIMEOUT STRING_ARG free($2); } ; +redis_replica_command_timeout: VAR_CACHEDB_REDISREPLICACOMMANDTIMEOUT STRING_ARG + { + #if defined(USE_CACHEDB) && defined(USE_REDIS) + OUTYY(("P(redis_replica_command_timeout:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2, "0") != 0) + yyerror("redis command timeout value expected"); + else cfg_parser->cfg->redis_replica_command_timeout = atoi($2); + #else + OUTYY(("P(Compiled without cachedb or redis, ignoring)\n")); + #endif + free($2); + } + ; redis_connect_timeout: VAR_CACHEDB_REDISCONNECTTIMEOUT STRING_ARG { #if defined(USE_CACHEDB) && defined(USE_REDIS) @@ -4013,6 +4112,19 @@ redis_connect_timeout: VAR_CACHEDB_REDISCONNECTTIMEOUT STRING_ARG free($2); } ; +redis_replica_connect_timeout: VAR_CACHEDB_REDISREPLICACONNECTTIMEOUT STRING_ARG + { + #if defined(USE_CACHEDB) && defined(USE_REDIS) + OUTYY(("P(redis_replica_connect_timeout:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2, "0") != 0) + yyerror("redis connect timeout value expected"); + else cfg_parser->cfg->redis_replica_connect_timeout = atoi($2); + #else + OUTYY(("P(Compiled without cachedb or redis, ignoring)\n")); + #endif + free($2); + } + ; redis_expire_records: VAR_CACHEDB_REDISEXPIRERECORDS STRING_ARG { #if defined(USE_CACHEDB) && defined(USE_REDIS) @@ -4041,6 +4153,21 @@ redis_logical_db: VAR_CACHEDB_REDISLOGICALDB STRING_ARG free($2); } ; +redis_replica_logical_db: VAR_CACHEDB_REDISREPLICALOGICALDB STRING_ARG + { + #if defined(USE_CACHEDB) && defined(USE_REDIS) + int db; + OUTYY(("P(redis_replica_logical_db:%s)\n", $2)); + db = atoi($2); + if((db == 0 && strcmp($2, "0") != 0) || db < 0) + yyerror("valid redis logical database index expected"); + else cfg_parser->cfg->redis_replica_logical_db = db; + #else + OUTYY(("P(Compiled without cachedb or redis, ignoring)\n")); + #endif + free($2); + } + ; server_tcp_connection_limit: VAR_TCP_CONNECTION_LIMIT STRING_ARG STRING_ARG { OUTYY(("P(server_tcp_connection_limit:%s %s)\n", $2, $3)); diff --git a/util/data/dname.c b/util/data/dname.c index 76b2ec7d6d8a..f08760e2f9fc 100644 --- a/util/data/dname.c +++ b/util/data/dname.c @@ -644,24 +644,24 @@ void dname_str(uint8_t* dname, char* str) if(!dname || !*dname) { *s++ = '.'; *s = 0; - return; + goto out; } lablen = *dname++; while(lablen) { if(lablen > LDNS_MAX_LABELLEN) { *s++ = '#'; *s = 0; - return; + goto out; } len += lablen+1; - if(len >= LDNS_MAX_DOMAINLEN-1) { + if(len >= LDNS_MAX_DOMAINLEN) { *s++ = '&'; *s = 0; - return; + goto out; } while(lablen--) { - if(isalnum((unsigned char)*dname) - || *dname == '-' || *dname == '_' + if(isalnum((unsigned char)*dname) + || *dname == '-' || *dname == '_' || *dname == '*') *s++ = *(char*)dname++; else { @@ -673,6 +673,10 @@ void dname_str(uint8_t* dname, char* str) lablen = *dname++; } *s = 0; + +out: + log_assert(s - str < LDNS_MAX_DOMAINLEN); + return; } int diff --git a/util/data/dname.h b/util/data/dname.h index 15e28bd973bb..6e4cf7ea3be7 100644 --- a/util/data/dname.h +++ b/util/data/dname.h @@ -242,11 +242,12 @@ void dname_print(FILE* out, struct sldns_buffer* pkt, uint8_t* dname); /** * Debug helper. Print dname to given string buffer (string buffer must - * be at least 255 chars + 1 for the 0, in printable form. + * be at least 255 chars, in printable form. * This may lose information (? for nonprintable characters, or & if * the name is too long, # for a bad label length). + * Upon return, the buffer will always have a terminating \0 value. * @param dname: uncompressed wireformat. - * @param str: buffer of 255+1 length. + * @param str: buffer of at least 255 length. */ void dname_str(uint8_t* dname, char* str); diff --git a/util/data/msgreply.c b/util/data/msgreply.c index 78e4fb1c323a..e98dce133039 100644 --- a/util/data/msgreply.c +++ b/util/data/msgreply.c @@ -66,7 +66,7 @@ time_t MIN_NEG_TTL = 0; /** If we serve expired entries and prefetch them */ int SERVE_EXPIRED = 0; /** Time to serve records after expiration */ -time_t SERVE_EXPIRED_TTL = 0; +time_t SERVE_EXPIRED_TTL = 86400; /** Reset serve expired TTL after failed update attempt */ time_t SERVE_EXPIRED_TTL_RESET = 0; /** TTL to use for expired records */ @@ -965,15 +965,11 @@ void log_reply_info(enum verbosity_value v, struct query_info *qinf, struct sockaddr_storage *addr, socklen_t addrlen, struct timeval dur, int cached, struct sldns_buffer *rmsg, struct sockaddr_storage* daddr, - enum comm_point_type tp) + enum comm_point_type tp, void* ssl) { - char qname_buf[LDNS_MAX_DOMAINLEN+1]; char clientip_buf[128]; char rcode_buf[16]; - char type_buf[16]; - char class_buf[16]; char dest_buf[160]; - size_t pktlen; uint16_t rcode = FLAGS_GET_RCODE(sldns_buffer_read_u16_at(rmsg, 2)); if(verbosity < v) @@ -1004,9 +1000,9 @@ log_reply_info(enum verbosity_value v, struct query_info *qinf, (int)daddr->ss_family); } comm = "udp"; - if(tp == comm_tcp) comm = "tcp"; - else if(tp == comm_tcp_accept) comm = "tcp"; - else if(tp == comm_http) comm = "dot"; + if(tp == comm_tcp) comm = (ssl?"dot":"tcp"); + else if(tp == comm_tcp_accept) comm = (ssl?"dot":"tcp"); + else if(tp == comm_http) comm = "doh"; else if(tp == comm_local) comm = "unix"; else if(tp == comm_raw) comm = "raw"; snprintf(dest_buf, sizeof(dest_buf), " on %s %s %d", @@ -1022,6 +1018,10 @@ log_reply_info(enum verbosity_value v, struct query_info *qinf, else log_info("%s - - - %s - - -%s", clientip_buf, rcode_buf, dest_buf); } else { + char qname_buf[LDNS_MAX_DOMAINLEN]; + char type_buf[16]; + char class_buf[16]; + size_t pktlen; if(qinf->qname) dname_str(qinf->qname, qname_buf); else snprintf(qname_buf, sizeof(qname_buf), "null"); diff --git a/util/data/msgreply.h b/util/data/msgreply.h index d1c2bfa4bdfc..9c701f07d0c4 100644 --- a/util/data/msgreply.h +++ b/util/data/msgreply.h @@ -554,11 +554,13 @@ void log_dns_msg(const char* str, struct query_info* qinfo, * @param rmsg: sldns buffer packet. * @param daddr: if not NULL, the destination address and port are logged. * @param tp: type of the comm point for logging destination connection type. + * @param ssl: the SSL pointer of the connection, to see if the connection + * type is tcp or dot. */ void log_reply_info(enum verbosity_value v, struct query_info *qinf, struct sockaddr_storage *addr, socklen_t addrlen, struct timeval dur, int cached, struct sldns_buffer *rmsg, struct sockaddr_storage* daddr, - enum comm_point_type tp); + enum comm_point_type tp, void* ssl); /** * Print string with neat domain name, type, class from query info. diff --git a/util/edns.c b/util/edns.c index ee95a6912209..40b7c94471fe 100644 --- a/util/edns.c +++ b/util/edns.c @@ -131,6 +131,29 @@ edns_string_addr_lookup(rbtree_type* tree, struct sockaddr_storage* addr, return (struct edns_string_addr*)addr_tree_lookup(tree, addr, addrlen); } +size_t +edns_strings_get_mem(struct edns_strings* edns_strings) +{ + if(!edns_strings) return 0; + return regional_get_mem(edns_strings->region) + sizeof(*edns_strings); +} + +void +edns_strings_swap_tree(struct edns_strings* edns_strings, + struct edns_strings* data) +{ + rbtree_type tree = edns_strings->client_strings; + uint16_t opcode = edns_strings->client_string_opcode; + struct regional* region = edns_strings->region; + + edns_strings->client_strings = data->client_strings; + edns_strings->client_string_opcode = data->client_string_opcode; + edns_strings->region = data->region; + data->client_strings = tree; + data->client_string_opcode = opcode; + data->region = region; +} + uint8_t* edns_cookie_server_hash(const uint8_t* in, const uint8_t* secret, int v4, uint8_t* hash) diff --git a/util/edns.h b/util/edns.h index 47ccb1ad2cd3..5a991fc57bbc 100644 --- a/util/edns.h +++ b/util/edns.h @@ -142,6 +142,22 @@ edns_string_addr_lookup(rbtree_type* tree, struct sockaddr_storage* addr, socklen_t addrlen); /** + * Get memory usage of edns strings. + * @param edns_strings: the edns strings + * @return memory usage + */ +size_t edns_strings_get_mem(struct edns_strings* edns_strings); + +/** + * Swap internal tree with preallocated entries. + * @param edns_strings: the edns strings structure. + * @param data: the data structure used to take elements from. This contains + * the old elements on return. + */ +void edns_strings_swap_tree(struct edns_strings* edns_strings, + struct edns_strings* data); + +/** * Compute the interoperable DNS cookie (RFC9018) hash. * @param in: buffer input for the hash generation. It needs to be: * Client Cookie | Version | Reserved | Timestamp | Client-IP diff --git a/util/fptr_wlist.c b/util/fptr_wlist.c index e94ec5bbce85..c6f3ca24aeed 100644 --- a/util/fptr_wlist.c +++ b/util/fptr_wlist.c @@ -74,6 +74,7 @@ #include "libunbound/worker.h" #include "util/tube.h" #include "util/config_file.h" +#include "daemon/remote.h" #ifdef UB_ON_WINDOWS #include "winrc/win_svc.h" #endif @@ -121,6 +122,7 @@ fptr_whitelist_comm_point_raw(comm_point_callback_type *fptr) else if(fptr == &tube_handle_write) return 1; else if(fptr == &remote_accept_callback) return 1; else if(fptr == &remote_control_callback) return 1; + else if(fptr == &fast_reload_client_callback) return 1; return 0; } @@ -188,6 +190,7 @@ fptr_whitelist_event(void (*fptr)(int, short, void *)) #ifdef HAVE_NGTCP2 else if(fptr == &comm_point_doq_callback) return 1; #endif + else if(fptr == &fast_reload_service_cb) return 1; #ifdef USE_DNSTAP else if(fptr == &dtio_output_cb) return 1; else if(fptr == &dtio_cmd_cb) return 1; diff --git a/util/iana_ports.inc b/util/iana_ports.inc index c3903563654d..198a47eb1777 100644 --- a/util/iana_ports.inc +++ b/util/iana_ports.inc @@ -1,6 +1,4 @@ 1, -2, -3, 5, 7, 9, @@ -2426,6 +2424,7 @@ 2791, 2792, 2793, +2794, 2795, 2796, 2797, @@ -4358,6 +4357,7 @@ 5911, 5912, 5913, +5914, 5963, 5968, 5969, @@ -5477,6 +5477,7 @@ 44900, 45000, 45054, +45185, 45514, 45678, 45825, diff --git a/util/log.c b/util/log.c index a44758728b06..b75cf065feb8 100644 --- a/util/log.c +++ b/util/log.c @@ -281,7 +281,7 @@ log_vmsg(int pri, const char* type, if(log_time_iso && log_time_asc) { char tzbuf[16]; struct timeval tv; - struct tm tm, *tm_p; + struct tm *tm_p; if(gettimeofday(&tv, NULL) < 0) memset(&tv, 0, sizeof(tv)); now = (time_t)tv.tv_sec; diff --git a/util/module.c b/util/module.c index 90a155b5e8aa..d2c21b49d604 100644 --- a/util/module.c +++ b/util/module.c @@ -135,7 +135,7 @@ char* errinf_to_str_bogus(struct module_qstate* qstate, struct regional* region) char* p = buf; size_t left = sizeof(buf); struct errinf_strlist* s; - char dname[LDNS_MAX_DOMAINLEN+1]; + char dname[LDNS_MAX_DOMAINLEN]; char t[16], c[16]; sldns_wire2str_type_buf(qstate->qinfo.qtype, t, sizeof(t)); sldns_wire2str_class_buf(qstate->qinfo.qclass, c, sizeof(c)); @@ -178,7 +178,7 @@ char* errinf_to_str_servfail(struct module_qstate* qstate) char* p = buf; size_t left = sizeof(buf); struct errinf_strlist* s; - char dname[LDNS_MAX_DOMAINLEN+1]; + char dname[LDNS_MAX_DOMAINLEN]; char t[16], c[16]; sldns_wire2str_type_buf(qstate->qinfo.qtype, t, sizeof(t)); sldns_wire2str_class_buf(qstate->qinfo.qclass, c, sizeof(c)); @@ -218,7 +218,7 @@ char* errinf_to_str_misc(struct module_qstate* qstate) void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr) { char buf[1024]; - char dname[LDNS_MAX_DOMAINLEN+1]; + char dname[LDNS_MAX_DOMAINLEN]; char t[16], c[16]; if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !rr) return; @@ -232,7 +232,7 @@ void errinf_rrset(struct module_qstate* qstate, struct ub_packed_rrset_key *rr) void errinf_dname(struct module_qstate* qstate, const char* str, uint8_t* dname) { char b[1024]; - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; if((qstate->env->cfg->val_log_level < 2 && !qstate->env->cfg->log_servfail) || !str || !dname) return; dname_str(dname, buf); diff --git a/util/module.h b/util/module.h index abad3c8dd114..edce4a523759 100644 --- a/util/module.h +++ b/util/module.h @@ -177,6 +177,7 @@ struct val_anchors; struct val_neg_cache; struct iter_forwards; struct iter_hints; +struct views; struct respip_set; struct respip_client_info; struct respip_addr_info; @@ -524,6 +525,10 @@ struct module_env { * data structure. */ struct iter_hints* hints; + /** views structure containing view tree */ + struct views* views; + /** response-ip set with associated actions and tags. */ + struct respip_set* respip_set; /** module specific data. indexed by module id. */ void* modinfo[MAX_MODULE]; diff --git a/util/net_help.c b/util/net_help.c index 5cf702ef9bca..8eca6b757ca8 100644 --- a/util/net_help.c +++ b/util/net_help.c @@ -92,11 +92,13 @@ int RRSET_ROUNDROBIN = 1; /** log tag queries with name instead of 'info' for filtering */ int LOG_TAG_QUERYREPLY = 0; +#ifdef HAVE_SSL static struct tls_session_ticket_key { unsigned char *key_name; unsigned char *aes_key; unsigned char *hmac_key; } *ticket_keys; +#endif /* HAVE_SSL */ #ifdef HAVE_SSL /** @@ -544,7 +546,7 @@ void log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name, uint16_t type, uint16_t dclass) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; char t[12], c[12]; const char *ts, *cs; if(verbosity < v) @@ -575,7 +577,7 @@ log_nametypeclass(enum verbosity_value v, const char* str, uint8_t* name, void log_query_in(const char* str, uint8_t* name, uint16_t type, uint16_t dclass) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; char t[12], c[12]; const char *ts, *cs; dname_str(name, buf); @@ -608,7 +610,7 @@ void log_name_addr(enum verbosity_value v, const char* str, uint8_t* zone, { uint16_t port; const char* family = "unknown_family "; - char namebuf[LDNS_MAX_DOMAINLEN+1]; + char namebuf[LDNS_MAX_DOMAINLEN]; char dest[100]; int af = (int)((struct sockaddr_in*)addr)->sin_family; void* sinaddr = &((struct sockaddr_in*)addr)->sin_addr; @@ -728,6 +730,52 @@ sockaddr_cmp_addr(struct sockaddr_storage* addr1, socklen_t len1, } int +sockaddr_cmp_scopeid(struct sockaddr_storage* addr1, socklen_t len1, + struct sockaddr_storage* addr2, socklen_t len2) +{ + struct sockaddr_in* p1_in = (struct sockaddr_in*)addr1; + struct sockaddr_in* p2_in = (struct sockaddr_in*)addr2; + struct sockaddr_in6* p1_in6 = (struct sockaddr_in6*)addr1; + struct sockaddr_in6* p2_in6 = (struct sockaddr_in6*)addr2; + if(len1 < len2) + return -1; + if(len1 > len2) + return 1; + log_assert(len1 == len2); + if( p1_in->sin_family < p2_in->sin_family) + return -1; + if( p1_in->sin_family > p2_in->sin_family) + return 1; + log_assert( p1_in->sin_family == p2_in->sin_family ); + /* compare ip4 */ + if( p1_in->sin_family == AF_INET ) { + /* just order it, ntohs not required */ + if(p1_in->sin_port < p2_in->sin_port) + return -1; + if(p1_in->sin_port > p2_in->sin_port) + return 1; + log_assert(p1_in->sin_port == p2_in->sin_port); + return memcmp(&p1_in->sin_addr, &p2_in->sin_addr, INET_SIZE); + } else if (p1_in6->sin6_family == AF_INET6) { + /* just order it, ntohs not required */ + if(p1_in6->sin6_port < p2_in6->sin6_port) + return -1; + if(p1_in6->sin6_port > p2_in6->sin6_port) + return 1; + if(p1_in6->sin6_scope_id < p2_in6->sin6_scope_id) + return -1; + if(p1_in6->sin6_scope_id > p2_in6->sin6_scope_id) + return 1; + log_assert(p1_in6->sin6_port == p2_in6->sin6_port); + return memcmp(&p1_in6->sin6_addr, &p2_in6->sin6_addr, + INET6_SIZE); + } else { + /* eek unknown type, perform this comparison for sanity. */ + return memcmp(addr1, addr2, len1); + } +} + +int addr_is_ip6(struct sockaddr_storage* addr, socklen_t len) { if(len == (socklen_t)sizeof(struct sockaddr_in6) && @@ -1116,8 +1164,29 @@ log_cert(unsigned level, const char* str, void* cert) } #endif /* HAVE_SSL */ +#if defined(HAVE_SSL) && defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB) +static int +dot_alpn_select_cb(SSL* ATTR_UNUSED(ssl), const unsigned char** out, + unsigned char* outlen, const unsigned char* in, unsigned int inlen, + void* ATTR_UNUSED(arg)) +{ + static const unsigned char alpns[] = { 3, 'd', 'o', 't' }; + unsigned char* tmp_out; + int ret; + ret = SSL_select_next_proto(&tmp_out, outlen, alpns, sizeof(alpns), in, inlen); + if(ret == OPENSSL_NPN_NO_OVERLAP) { + /* Client sent ALPN but no overlap. Should have been error, + * but for privacy we continue without ALPN (e.g., if certain + * ALPNs are blocked) */ + return SSL_TLSEXT_ERR_NOACK; + } + *out = tmp_out; + return SSL_TLSEXT_ERR_OK; +} +#endif + #if defined(HAVE_SSL) && defined(HAVE_NGHTTP2) && defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB) -static int alpn_select_cb(SSL* ATTR_UNUSED(ssl), const unsigned char** out, +static int doh_alpn_select_cb(SSL* ATTR_UNUSED(ssl), const unsigned char** out, unsigned char* outlen, const unsigned char* in, unsigned int inlen, void* ATTR_UNUSED(arg)) { @@ -1131,6 +1200,24 @@ static int alpn_select_cb(SSL* ATTR_UNUSED(ssl), const unsigned char** out, } #endif +#ifdef HAVE_SSL +/* setup the callback for ticket keys */ +static int +setup_ticket_keys_cb(void* sslctx) +{ +# ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB + if(SSL_CTX_set_tlsext_ticket_key_evp_cb(sslctx, tls_session_ticket_key_cb) == 0) { + return 0; + } +# else + if(SSL_CTX_set_tlsext_ticket_key_cb(sslctx, tls_session_ticket_key_cb) == 0) { + return 0; + } +# endif + return 1; +} +#endif /* HAVE_SSL */ + int listen_sslctx_setup(void* ctxt) { @@ -1202,9 +1289,6 @@ listen_sslctx_setup(void* ctxt) #ifdef HAVE_SSL_CTX_SET_SECURITY_LEVEL SSL_CTX_set_security_level(ctx, 0); #endif -#if defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB) && defined(HAVE_NGHTTP2) - SSL_CTX_set_alpn_select_cb(ctx, alpn_select_cb, NULL); -#endif #else (void)ctxt; #endif /* HAVE_SSL */ @@ -1239,7 +1323,10 @@ listen_sslctx_setup_2(void* ctxt) #endif /* HAVE_SSL */ } -void* listen_sslctx_create(char* key, char* pem, char* verifypem) +void* listen_sslctx_create(const char* key, const char* pem, + const char* verifypem, const char* tls_ciphers, + const char* tls_ciphersuites, int set_ticket_keys_cb, + int is_dot, int is_doh) { #ifdef HAVE_SSL SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method()); @@ -1290,11 +1377,52 @@ void* listen_sslctx_create(char* key, char* pem, char* verifypem) verifypem)); SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER|SSL_VERIFY_FAIL_IF_NO_PEER_CERT, NULL); } + if(tls_ciphers && tls_ciphers[0]) { + if (!SSL_CTX_set_cipher_list(ctx, tls_ciphers)) { + log_err("failed to set tls-cipher %s", + tls_ciphers); + log_crypto_err("Error in SSL_CTX_set_cipher_list"); + SSL_CTX_free(ctx); + return NULL; + } + } +#ifdef HAVE_SSL_CTX_SET_CIPHERSUITES + if(tls_ciphersuites && tls_ciphersuites[0]) { + if (!SSL_CTX_set_ciphersuites(ctx, tls_ciphersuites)) { + log_err("failed to set tls-ciphersuites %s", + tls_ciphersuites); + log_crypto_err("Error in SSL_CTX_set_ciphersuites"); + SSL_CTX_free(ctx); + return NULL; + } + } +#else + (void)tls_ciphersuites; /* variable unused. */ +#endif /* HAVE_SSL_CTX_SET_CIPHERSUITES */ + if(set_ticket_keys_cb) { + if(!setup_ticket_keys_cb(ctx)) { + log_crypto_err("no support for TLS session ticket"); + SSL_CTX_free(ctx); + return NULL; + } + } + /* setup ALPN */ +#if defined(HAVE_SSL_CTX_SET_ALPN_SELECT_CB) + if(is_dot) { + SSL_CTX_set_alpn_select_cb(ctx, dot_alpn_select_cb, NULL); + } else if(is_doh) { +#if defined(HAVE_NGHTTP2) + SSL_CTX_set_alpn_select_cb(ctx, doh_alpn_select_cb, NULL); +#endif + } +#endif /* HAVE_SSL_CTX_SET_ALPN_SELECT_CB */ return ctx; #else (void)key; (void)pem; (void)verifypem; + (void)tls_ciphers; (void)tls_ciphersuites; + (void)set_ticket_keys_cb; (void)is_dot; (void)is_doh; return NULL; -#endif +#endif /* HAVE_SSL */ } #ifdef USE_WINSOCK @@ -1654,7 +1782,7 @@ void ub_openssl_lock_delete(void) #endif /* OPENSSL_THREADS */ } -int listen_sslctx_setup_ticket_keys(void* sslctx, struct config_strlist* tls_session_ticket_keys) { +int listen_sslctx_setup_ticket_keys(struct config_strlist* tls_session_ticket_keys) { #ifdef HAVE_SSL size_t s = 1; struct config_strlist* p; @@ -1700,24 +1828,11 @@ int listen_sslctx_setup_ticket_keys(void* sslctx, struct config_strlist* tls_ses } /* terminate array with NULL key name entry */ keys->key_name = NULL; -# ifdef HAVE_SSL_CTX_SET_TLSEXT_TICKET_KEY_EVP_CB - if(SSL_CTX_set_tlsext_ticket_key_evp_cb(sslctx, tls_session_ticket_key_cb) == 0) { - log_err("no support for TLS session ticket"); - return 0; - } -# else - if(SSL_CTX_set_tlsext_ticket_key_cb(sslctx, tls_session_ticket_key_cb) == 0) { - log_err("no support for TLS session ticket"); - return 0; - } -# endif return 1; #else - (void)sslctx; (void)tls_session_ticket_keys; return 0; #endif - } #ifdef HAVE_SSL @@ -1828,6 +1943,7 @@ int tls_session_ticket_key_cb(SSL *ATTR_UNUSED(sslctx), unsigned char* key_name, } #endif /* HAVE_SSL */ +#ifdef HAVE_SSL void listen_sslctx_delete_ticket_keys(void) { @@ -1845,6 +1961,7 @@ listen_sslctx_delete_ticket_keys(void) free(ticket_keys); ticket_keys = NULL; } +#endif /* HAVE_SSL */ # ifndef USE_WINSOCK char* diff --git a/util/net_help.h b/util/net_help.h index 28245ea0c1ee..278e370a268d 100644 --- a/util/net_help.h +++ b/util/net_help.h @@ -290,6 +290,18 @@ int sockaddr_cmp_addr(struct sockaddr_storage* addr1, socklen_t len1, struct sockaddr_storage* addr2, socklen_t len2); /** + * Compare two sockaddrs. Imposes an ordering on the addresses. + * Compares address and port. It also compares scope_id for ip6. + * @param addr1: address 1. + * @param len1: lengths of addr1. + * @param addr2: address 2. + * @param len2: lengths of addr2. + * @return: 0 if addr1 == addr2. -1 if addr1 is smaller, +1 if larger. + */ +int sockaddr_cmp_scopeid(struct sockaddr_storage* addr1, socklen_t len1, + struct sockaddr_storage* addr2, socklen_t len2); + +/** * Checkout address family. * @param addr: the sockaddr to examine. * @param len: the length of addr. @@ -476,14 +488,23 @@ int listen_sslctx_setup(void* ctxt); */ void listen_sslctx_setup_2(void* ctxt); -/** +/** * create SSL listen context * @param key: private key file. * @param pem: public key cert. * @param verifypem: if nonNULL, verifylocation file. + * @param tls_ciphers: if non empty string, tls ciphers to use. + * @param tls_ciphersuites: if non empty string, tls ciphersuites to use. + * @param set_ticket_keys_cb: if the callback for configured ticket keys needs + * to be set. + * @param is_dot: if the TLS connection is for DoT to set the appropriate ALPN. + * @param is_doh: if the TLS connection is for DoH to set the appropriate ALPN. * return SSL_CTX* or NULL on failure (logged). */ -void* listen_sslctx_create(char* key, char* pem, char* verifypem); +void* listen_sslctx_create(const char* key, const char* pem, + const char* verifypem, const char* tls_ciphers, + const char* tls_ciphersuites, int set_ticket_keys_cb, + int is_dot, int is_doh); /** * create SSL connect context @@ -541,12 +562,10 @@ void ub_openssl_lock_delete(void); /** * setup TLS session ticket - * @param sslctx: the SSL_CTX to use (from connect_sslctx_create()) * @param tls_session_ticket_keys: TLS ticket secret filenames * @return false on failure (alloc failure). */ -int listen_sslctx_setup_ticket_keys(void* sslctx, - struct config_strlist* tls_session_ticket_keys); +int listen_sslctx_setup_ticket_keys(struct config_strlist* tls_session_ticket_keys); /** Free memory used for TLS session ticket keys */ void listen_sslctx_delete_ticket_keys(void); diff --git a/util/netevent.c b/util/netevent.c index b36f00f1a2aa..0d0fff429c03 100644 --- a/util/netevent.c +++ b/util/netevent.c @@ -314,6 +314,11 @@ struct ub_event_base* comm_base_internal(struct comm_base* b) return b->eb->base; } +struct ub_event* comm_point_internal(struct comm_point* c) +{ + return c->ev->ev; +} + /** see if errno for udp has to be logged or not uses globals */ static int udp_send_errno_needs_log(struct sockaddr* addr, socklen_t addrlen) @@ -369,6 +374,15 @@ udp_send_errno_needs_log(struct sockaddr* addr, socklen_t addrlen) (struct sockaddr_storage*)addr, addrlen) && verbosity < VERB_DETAIL) return 0; +# ifdef ENOTCONN + /* For 0.0.0.0, ::0 targets it can return that socket is not connected. + * This can be ignored, and the address skipped. It remains + * possible to send there for completeness in configuration. */ + if(errno == ENOTCONN && addr_is_any( + (struct sockaddr_storage*)addr, addrlen) && + verbosity < VERB_DETAIL) + return 0; +# endif return 1; } @@ -442,7 +456,11 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet, int pret; memset(&p, 0, sizeof(p)); p.fd = c->fd; - p.events = POLLOUT | POLLERR | POLLHUP; + p.events = POLLOUT +#ifndef USE_WINSOCK + | POLLERR | POLLHUP +#endif + ; # ifndef USE_WINSOCK pret = poll(&p, 1, SEND_BLOCKED_WAIT_TIMEOUT); # else @@ -465,7 +483,7 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet, # ifdef EWOULDBLOCK errno != EWOULDBLOCK && # endif - errno != ENOBUFS + errno != ENOMEM && errno != ENOBUFS #else WSAGetLastError() != WSAEINPROGRESS && WSAGetLastError() != WSAEINTR && @@ -478,15 +496,19 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet, return 0; } else if((pret < 0 && #ifndef USE_WINSOCK - errno == ENOBUFS + ( errno == ENOBUFS /* Maybe some systems */ + || errno == ENOMEM /* Linux */ + || errno == EAGAIN) /* Macos, solaris, openbsd */ #else WSAGetLastError() == WSAENOBUFS #endif ) || (send_nobufs && retries > 0)) { - /* ENOBUFS, and poll returned without + /* ENOBUFS/ENOMEM/EAGAIN, and poll + * returned without * a timeout. Or the retried send call - * returned ENOBUFS. It is good to - * wait a bit for the error to clear. */ + * returned ENOBUFS/ENOMEM/EAGAIN. + * It is good to wait a bit for the + * error to clear. */ /* The timeout is 20*(2^(retries+1)), * it increases exponentially, starting * at 40 msec. After 5 tries, 1240 msec @@ -496,20 +518,18 @@ comm_point_send_udp_msg(struct comm_point *c, sldns_buffer* packet, #ifndef USE_WINSOCK pret = poll(NULL, 0, (SEND_BLOCKED_WAIT_TIMEOUT/10)<<(retries+1)); #else - pret = WSAPoll(NULL, 0, (SEND_BLOCKED_WAIT_TIMEOUT/10)<<(retries+1)); + Sleep((SEND_BLOCKED_WAIT_TIMEOUT/10)<<(retries+1)); + pret = 0; #endif - if(pret < 0 && + if(pret < 0 #ifndef USE_WINSOCK - errno != EAGAIN && errno != EINTR && + && errno != EAGAIN && errno != EINTR && # ifdef EWOULDBLOCK errno != EWOULDBLOCK && # endif - errno != ENOBUFS + errno != ENOMEM && errno != ENOBUFS #else - WSAGetLastError() != WSAEINPROGRESS && - WSAGetLastError() != WSAEINTR && - WSAGetLastError() != WSAENOBUFS && - WSAGetLastError() != WSAEWOULDBLOCK + /* Sleep does not error */ #endif ) { log_err("poll udp out timer failed: %s", @@ -751,7 +771,11 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet, int pret; memset(&p, 0, sizeof(p)); p.fd = c->fd; - p.events = POLLOUT | POLLERR | POLLHUP; + p.events = POLLOUT +#ifndef USE_WINSOCK + | POLLERR | POLLHUP +#endif + ; # ifndef USE_WINSOCK pret = poll(&p, 1, SEND_BLOCKED_WAIT_TIMEOUT); # else @@ -774,7 +798,7 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet, # ifdef EWOULDBLOCK errno != EWOULDBLOCK && # endif - errno != ENOBUFS + errno != ENOMEM && errno != ENOBUFS #else WSAGetLastError() != WSAEINPROGRESS && WSAGetLastError() != WSAEINTR && @@ -787,15 +811,19 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet, return 0; } else if((pret < 0 && #ifndef USE_WINSOCK - errno == ENOBUFS + ( errno == ENOBUFS /* Maybe some systems */ + || errno == ENOMEM /* Linux */ + || errno == EAGAIN) /* Macos, solaris, openbsd */ #else WSAGetLastError() == WSAENOBUFS #endif ) || (send_nobufs && retries > 0)) { - /* ENOBUFS, and poll returned without + /* ENOBUFS/ENOMEM/EAGAIN, and poll + * returned without * a timeout. Or the retried send call - * returned ENOBUFS. It is good to - * wait a bit for the error to clear. */ + * returned ENOBUFS/ENOMEM/EAGAIN. + * It is good to wait a bit for the + * error to clear. */ /* The timeout is 20*(2^(retries+1)), * it increases exponentially, starting * at 40 msec. After 5 tries, 1240 msec @@ -805,20 +833,18 @@ comm_point_send_udp_msg_if(struct comm_point *c, sldns_buffer* packet, #ifndef USE_WINSOCK pret = poll(NULL, 0, (SEND_BLOCKED_WAIT_TIMEOUT/10)<<(retries+1)); #else - pret = WSAPoll(NULL, 0, (SEND_BLOCKED_WAIT_TIMEOUT/10)<<(retries+1)); + Sleep((SEND_BLOCKED_WAIT_TIMEOUT/10)<<(retries+1)); + pret = 0; #endif - if(pret < 0 && + if(pret < 0 #ifndef USE_WINSOCK - errno != EAGAIN && errno != EINTR && + && errno != EAGAIN && errno != EINTR && # ifdef EWOULDBLOCK errno != EWOULDBLOCK && # endif - errno != ENOBUFS -#else - WSAGetLastError() != WSAEINPROGRESS && - WSAGetLastError() != WSAEINTR && - WSAGetLastError() != WSAENOBUFS && - WSAGetLastError() != WSAEWOULDBLOCK + errno != ENOMEM && errno != ENOBUFS +#else /* USE_WINSOCK */ + /* Sleep does not error */ #endif ) { log_err("poll udp out timer failed: %s", @@ -2687,8 +2713,8 @@ comm_point_doq_callback(int fd, short event, void* arg) /** create new doq server socket structure */ static struct doq_server_socket* doq_server_socket_create(struct doq_table* table, struct ub_randstate* rnd, - const char* ssl_service_key, const char* ssl_service_pem, - struct comm_point* c, struct comm_base* base, struct config_file* cfg) + const void* quic_sslctx, struct comm_point* c, struct comm_base* base, + struct config_file* cfg) { size_t doq_buffer_size = 4096; /* bytes buffer size, for one packet. */ struct doq_server_socket* doq_socket; @@ -2699,69 +2725,29 @@ doq_server_socket_create(struct doq_table* table, struct ub_randstate* rnd, doq_socket->table = table; doq_socket->rnd = rnd; doq_socket->validate_addr = 1; - if(ssl_service_key == NULL || ssl_service_key[0]==0) { - log_err("doq server socket create: no tls-service-key"); - free(doq_socket); - return NULL; - } - if(ssl_service_pem == NULL || ssl_service_pem[0]==0) { - log_err("doq server socket create: no tls-service-pem"); - free(doq_socket); - return NULL; - } - doq_socket->ssl_service_key = strdup(ssl_service_key); - if(!doq_socket->ssl_service_key) { - free(doq_socket); - return NULL; - } - doq_socket->ssl_service_pem = strdup(ssl_service_pem); - if(!doq_socket->ssl_service_pem) { - free(doq_socket->ssl_service_key); - free(doq_socket); - return NULL; - } - doq_socket->ssl_verify_pem = NULL; /* the doq_socket has its own copy of the static secret, as * well as other config values, so that they do not need table.lock */ doq_socket->static_secret_len = table->static_secret_len; doq_socket->static_secret = memdup(table->static_secret, table->static_secret_len); if(!doq_socket->static_secret) { - free(doq_socket->ssl_service_key); - free(doq_socket->ssl_service_pem); - free(doq_socket->ssl_verify_pem); - free(doq_socket); - return NULL; - } - if(!doq_socket_setup_ctx(doq_socket)) { - free(doq_socket->ssl_service_key); - free(doq_socket->ssl_service_pem); - free(doq_socket->ssl_verify_pem); - free(doq_socket->static_secret); free(doq_socket); return NULL; } + doq_socket->ctx = (SSL_CTX*)quic_sslctx; doq_socket->idle_timeout = table->idle_timeout; doq_socket->sv_scidlen = table->sv_scidlen; doq_socket->cp = c; doq_socket->pkt_buf = sldns_buffer_new(doq_buffer_size); if(!doq_socket->pkt_buf) { - free(doq_socket->ssl_service_key); - free(doq_socket->ssl_service_pem); - free(doq_socket->ssl_verify_pem); free(doq_socket->static_secret); - SSL_CTX_free(doq_socket->ctx); free(doq_socket); return NULL; } doq_socket->blocked_pkt = sldns_buffer_new( sldns_buffer_capacity(doq_socket->pkt_buf)); if(!doq_socket->pkt_buf) { - free(doq_socket->ssl_service_key); - free(doq_socket->ssl_service_pem); - free(doq_socket->ssl_verify_pem); free(doq_socket->static_secret); - SSL_CTX_free(doq_socket->ctx); sldns_buffer_free(doq_socket->pkt_buf); free(doq_socket); return NULL; @@ -2769,11 +2755,7 @@ doq_server_socket_create(struct doq_table* table, struct ub_randstate* rnd, doq_socket->blocked_paddr = calloc(1, sizeof(*doq_socket->blocked_paddr)); if(!doq_socket->blocked_paddr) { - free(doq_socket->ssl_service_key); - free(doq_socket->ssl_service_pem); - free(doq_socket->ssl_verify_pem); free(doq_socket->static_secret); - SSL_CTX_free(doq_socket->ctx); sldns_buffer_free(doq_socket->pkt_buf); sldns_buffer_free(doq_socket->blocked_pkt); free(doq_socket); @@ -2781,11 +2763,7 @@ doq_server_socket_create(struct doq_table* table, struct ub_randstate* rnd, } doq_socket->timer = comm_timer_create(base, doq_timer_cb, doq_socket); if(!doq_socket->timer) { - free(doq_socket->ssl_service_key); - free(doq_socket->ssl_service_pem); - free(doq_socket->ssl_verify_pem); free(doq_socket->static_secret); - SSL_CTX_free(doq_socket->ctx); sldns_buffer_free(doq_socket->pkt_buf); sldns_buffer_free(doq_socket->blocked_pkt); free(doq_socket->blocked_paddr); @@ -2805,13 +2783,9 @@ doq_server_socket_delete(struct doq_server_socket* doq_socket) if(!doq_socket) return; free(doq_socket->static_secret); - SSL_CTX_free(doq_socket->ctx); #ifndef HAVE_NGTCP2_CRYPTO_QUICTLS_CONFIGURE_SERVER_CONTEXT free(doq_socket->quic_method); #endif - free(doq_socket->ssl_service_key); - free(doq_socket->ssl_service_pem); - free(doq_socket->ssl_verify_pem); sldns_buffer_free(doq_socket->pkt_buf); sldns_buffer_free(doq_socket->blocked_pkt); free(doq_socket->blocked_paddr); @@ -2845,6 +2819,7 @@ static int doq_lookup_conn_stream(struct comm_reply* repinfo, struct comm_point* c, struct doq_conn** conn, struct doq_stream** stream) { + log_assert(c->doq_socket); if(c->doq_socket->current_conn) { *conn = c->doq_socket->current_conn; } else { @@ -3084,7 +3059,7 @@ int comm_point_perform_accept(struct comm_point* c, if(verbosity >= 3) log_err_addr("accept rejected", "connection limit exceeded", addr, *addrlen); - close(new_fd); + sock_close(new_fd); return -1; } } @@ -3185,6 +3160,40 @@ static int http2_submit_settings(struct http2_session* h2_session) } #endif /* HAVE_NGHTTP2 */ +#ifdef HAVE_NGHTTP2 +/** Delete http2 stream. After session delete or stream close callback */ +static void http2_stream_delete(struct http2_session* h2_session, + struct http2_stream* h2_stream) +{ + if(h2_stream->mesh_state) { + mesh_state_remove_reply(h2_stream->mesh, h2_stream->mesh_state, + h2_session->c); + h2_stream->mesh_state = NULL; + } + http2_req_stream_clear(h2_stream); + free(h2_stream); +} +#endif /* HAVE_NGHTTP2 */ + +/** delete http2 session server. After closing connection. */ +static void http2_session_server_delete(struct http2_session* h2_session) +{ +#ifdef HAVE_NGHTTP2 + struct http2_stream* h2_stream, *next; + nghttp2_session_del(h2_session->session); /* NULL input is fine */ + h2_session->session = NULL; + for(h2_stream = h2_session->first_stream; h2_stream;) { + next = h2_stream->next; + http2_stream_delete(h2_session, h2_stream); + h2_stream = next; + } + h2_session->first_stream = NULL; + h2_session->is_drop = 0; + h2_session->postpone_drop = 0; + h2_session->c->h2_stream = NULL; +#endif + (void)h2_session; +} void comm_point_tcp_accept_callback(int fd, short event, void* arg) @@ -3223,6 +3232,8 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg) if(!c_hdl->h2_session || !http2_submit_settings(c_hdl->h2_session)) { log_warn("failed to submit http2 settings"); + if(c_hdl->h2_session) + http2_session_server_delete(c_hdl->h2_session); return; } if(!c->ssl) { @@ -3240,14 +3251,23 @@ comm_point_tcp_accept_callback(int fd, short event, void* arg) } if(!c_hdl->ev->ev) { log_warn("could not ub_event_new, dropped tcp"); +#ifdef HAVE_NGHTTP2 + if(c_hdl->type == comm_http && c_hdl->h2_session) + http2_session_server_delete(c_hdl->h2_session); +#endif return; } log_assert(fd != -1); (void)fd; new_fd = comm_point_perform_accept(c, &c_hdl->repinfo.remote_addr, &c_hdl->repinfo.remote_addrlen); - if(new_fd == -1) + if(new_fd == -1) { +#ifdef HAVE_NGHTTP2 + if(c_hdl->type == comm_http && c_hdl->h2_session) + http2_session_server_delete(c_hdl->h2_session); +#endif return; + } /* Copy remote_address to client_address. * Simplest way/time for streams to do that. */ c_hdl->repinfo.client_addrlen = c_hdl->repinfo.remote_addrlen; @@ -5062,19 +5082,6 @@ struct http2_stream* http2_stream_create(int32_t stream_id) h2_stream->stream_id = stream_id; return h2_stream; } - -/** Delete http2 stream. After session delete or stream close callback */ -static void http2_stream_delete(struct http2_session* h2_session, - struct http2_stream* h2_stream) -{ - if(h2_stream->mesh_state) { - mesh_state_remove_reply(h2_stream->mesh, h2_stream->mesh_state, - h2_session->c); - h2_stream->mesh_state = NULL; - } - http2_req_stream_clear(h2_stream); - free(h2_stream); -} #endif void http2_stream_add_meshstate(struct http2_stream* h2_stream, @@ -5091,26 +5098,6 @@ void http2_stream_remove_mesh_state(struct http2_stream* h2_stream) h2_stream->mesh_state = NULL; } -/** delete http2 session server. After closing connection. */ -static void http2_session_server_delete(struct http2_session* h2_session) -{ -#ifdef HAVE_NGHTTP2 - struct http2_stream* h2_stream, *next; - nghttp2_session_del(h2_session->session); /* NULL input is fine */ - h2_session->session = NULL; - for(h2_stream = h2_session->first_stream; h2_stream;) { - next = h2_stream->next; - http2_stream_delete(h2_session, h2_stream); - h2_stream = next; - } - h2_session->first_stream = NULL; - h2_session->is_drop = 0; - h2_session->postpone_drop = 0; - h2_session->c->h2_stream = NULL; -#endif - (void)h2_session; -} - #ifdef HAVE_NGHTTP2 void http2_session_add_stream(struct http2_session* h2_session, struct http2_stream* h2_stream) @@ -5861,8 +5848,8 @@ struct comm_point* comm_point_create_doq(struct comm_base *base, int fd, sldns_buffer* buffer, comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket, struct doq_table* table, - struct ub_randstate* rnd, const char* ssl_service_key, - const char* ssl_service_pem, struct config_file* cfg) + struct ub_randstate* rnd, const void* quic_sslctx, + struct config_file* cfg) { #ifdef HAVE_NGTCP2 struct comm_point* c = (struct comm_point*)calloc(1, @@ -5899,15 +5886,13 @@ comm_point_create_doq(struct comm_base *base, int fd, sldns_buffer* buffer, c->dnscrypt = 0; c->dnscrypt_buffer = NULL; #endif -#ifdef HAVE_NGTCP2 - c->doq_socket = doq_server_socket_create(table, rnd, ssl_service_key, - ssl_service_pem, c, base, cfg); + c->doq_socket = doq_server_socket_create(table, rnd, quic_sslctx, c, + base, cfg); if(!c->doq_socket) { log_err("could not create doq comm_point"); comm_point_delete(c); return NULL; } -#endif c->inuse = 0; c->callback = callback; c->cb_arg = callback_arg; @@ -5939,8 +5924,7 @@ comm_point_create_doq(struct comm_base *base, int fd, sldns_buffer* buffer, (void)socket; (void)rnd; (void)table; - (void)ssl_service_key; - (void)ssl_service_pem; + (void)quic_sslctx; (void)cfg; sock_close(fd); return NULL; @@ -6747,7 +6731,7 @@ comm_point_drop_reply(struct comm_reply* repinfo) reclaim_http_handler(repinfo->c); return; #ifdef HAVE_NGTCP2 - } else if(repinfo->c->type == comm_doq) { + } else if(repinfo->c->doq_socket) { doq_socket_drop_reply(repinfo); return; #endif @@ -6952,8 +6936,9 @@ comm_timer_is_set(struct comm_timer* timer) } size_t -comm_timer_get_mem(struct comm_timer* ATTR_UNUSED(timer)) +comm_timer_get_mem(struct comm_timer* timer) { + if(!timer) return 0; return sizeof(struct internal_timer); } diff --git a/util/netevent.h b/util/netevent.h index acc4887b11e3..96de0032cef6 100644 --- a/util/netevent.h +++ b/util/netevent.h @@ -548,6 +548,14 @@ void comm_base_set_slow_accept_handlers(struct comm_base* b, struct ub_event_base* comm_base_internal(struct comm_base* b); /** + * Access internal event structure. It is for use with + * ub_winsock_tcp_wouldblock on windows. + * @param c: comm point. + * @return event. + */ +struct ub_event* comm_point_internal(struct comm_point* c); + +/** * Create an UDP comm point. Calls malloc. * setups the structure with the parameters you provide. * @param base: in which base to alloc the commpoint. @@ -593,8 +601,7 @@ struct comm_point* comm_point_create_udp_ancil(struct comm_base* base, * @param socket: and opened socket properties will be passed to your callback function. * @param table: the doq connection table for the host. * @param rnd: random generator to use. - * @param ssl_service_key: the ssl service key file. - * @param ssl_service_pem: the ssl service pem file. + * @param quic_sslctx: the quic ssl context. * @param cfg: config file struct. * @return: returns the allocated communication point. NULL on error. * Sets timeout to NULL. Turns off TCP options. @@ -603,8 +610,8 @@ struct comm_point* comm_point_create_doq(struct comm_base* base, int fd, struct sldns_buffer* buffer, comm_point_callback_type* callback, void* callback_arg, struct unbound_socket* socket, struct doq_table* table, - struct ub_randstate* rnd, const char* ssl_service_key, - const char* ssl_service_pem, struct config_file* cfg); + struct ub_randstate* rnd, const void* quic_sslctx, + struct config_file* cfg); /** * Create a TCP listener comm point. Calls malloc. @@ -1045,12 +1052,6 @@ struct doq_server_socket { struct ub_randstate* rnd; /** if address validation is enabled */ uint8_t validate_addr; - /** the ssl service key file */ - char* ssl_service_key; - /** the ssl service pem file */ - char* ssl_service_pem; - /** the ssl verify pem file */ - char* ssl_verify_pem; /** the server scid length */ int sv_scidlen; /** the idle timeout in nanoseconds */ diff --git a/util/shm_side/shm_main.c b/util/shm_side/shm_main.c index 6fd1f5ea638c..751d6d649bc4 100644 --- a/util/shm_side/shm_main.c +++ b/util/shm_side/shm_main.c @@ -195,7 +195,7 @@ void shm_main_shutdown(struct daemon* daemon) { #ifdef HAVE_SHMGET /* web are OK, just disabled */ - if(!daemon->cfg->shm_enable) + if(!daemon->cfg->shm_enable || !daemon->shm_info) return; verbose(VERB_DETAIL, "SHM shutdown - KEY [%d] - ID CTL [%d] ARR [%d] - PTR CTL [%p] ARR [%p]", diff --git a/util/storage/dnstree.c b/util/storage/dnstree.c index eef393f91b69..93a0cc4c3300 100644 --- a/util/storage/dnstree.c +++ b/util/storage/dnstree.c @@ -75,7 +75,7 @@ int addr_tree_addrport_compare(const void* k1, const void* k2) { struct addr_tree_node* n1 = (struct addr_tree_node*)k1; struct addr_tree_node* n2 = (struct addr_tree_node*)k2; - return sockaddr_cmp(&n1->addr, n1->addrlen, &n2->addr, + return sockaddr_cmp_scopeid(&n1->addr, n1->addrlen, &n2->addr, n2->addrlen); } diff --git a/util/storage/lruhash.c b/util/storage/lruhash.c index aba9fcc1d83b..028b199aa614 100644 --- a/util/storage/lruhash.c +++ b/util/storage/lruhash.c @@ -562,6 +562,36 @@ lruhash_update_space_used(struct lruhash* table, void* cb_arg, int diff_size) } } +void lruhash_update_space_max(struct lruhash* table, void* cb_arg, size_t max) +{ + struct lruhash_entry *reclaimlist = NULL; + + fptr_ok(fptr_whitelist_hash_sizefunc(table->sizefunc)); + fptr_ok(fptr_whitelist_hash_delkeyfunc(table->delkeyfunc)); + fptr_ok(fptr_whitelist_hash_deldatafunc(table->deldatafunc)); + fptr_ok(fptr_whitelist_hash_markdelfunc(table->markdelfunc)); + + if(cb_arg == NULL) cb_arg = table->cb_arg; + + /* update space max */ + lock_quick_lock(&table->lock); + table->space_max = max; + + if(table->space_used > table->space_max) + reclaim_space(table, &reclaimlist); + + lock_quick_unlock(&table->lock); + + /* finish reclaim if any (outside of critical region) */ + while(reclaimlist) { + struct lruhash_entry* n = reclaimlist->overflow_next; + void* d = reclaimlist->data; + (*table->delkeyfunc)(reclaimlist->key, cb_arg); + (*table->deldatafunc)(d, cb_arg); + reclaimlist = n; + } +} + void lruhash_traverse(struct lruhash* h, int wr, void (*func)(struct lruhash_entry*, void*), void* arg) diff --git a/util/storage/lruhash.h b/util/storage/lruhash.h index 5ab488beb508..667eba59ce49 100644 --- a/util/storage/lruhash.h +++ b/util/storage/lruhash.h @@ -314,6 +314,16 @@ void lruhash_setmarkdel(struct lruhash* table, lruhash_markdelfunc_type md); void lruhash_update_space_used(struct lruhash* table, void* cb_override, int diff_size); +/** + * Update the max space for the hashtable. + * + * @param table: hash table. + * @param cb_override: if not NULL overrides the cb_arg for deletefunc. + * @param max: the new max. + */ +void lruhash_update_space_max(struct lruhash* table, void* cb_override, + size_t max); + /************************* getdns functions ************************/ /*** these are used by getdns only and not by unbound. ***/ diff --git a/util/storage/slabhash.c b/util/storage/slabhash.c index 62396e16a82d..b2bee0838d30 100644 --- a/util/storage/slabhash.c +++ b/util/storage/slabhash.c @@ -267,3 +267,12 @@ void get_slabhash_stats(struct slabhash* sh, long long* num, long long* collisio if (collisions != NULL) *collisions = max_collisions; } + +void slabhash_adjust_size(struct slabhash* sl, size_t max) +{ + size_t space_max = max / sl->size; + size_t i; + for(i=0; i<sl->size; i++) { + lruhash_update_space_max(sl->array[i], NULL, space_max); + } +} diff --git a/util/storage/slabhash.h b/util/storage/slabhash.h index 089847d9359b..d6d94a940e05 100644 --- a/util/storage/slabhash.h +++ b/util/storage/slabhash.h @@ -221,6 +221,13 @@ size_t count_slabhash_entries(struct slabhash* table); void get_slabhash_stats(struct slabhash* table, long long* entries_count, long long* max_collisions); +/** + * Adjust size of slabhash memory max + * @param table: slabbed hash table + * @param max: new max memory + */ +void slabhash_adjust_size(struct slabhash* table, size_t max); + /* --- test representation --- */ /** test structure contains test key */ struct slabhash_testkey { diff --git a/util/tcp_conn_limit.c b/util/tcp_conn_limit.c index d7d86a5407b5..284d89076d57 100644 --- a/util/tcp_conn_limit.c +++ b/util/tcp_conn_limit.c @@ -192,3 +192,14 @@ tcl_list_get_mem(struct tcl_list* tcl) if(!tcl) return 0; return sizeof(*tcl) + regional_get_mem(tcl->region); } + +void tcl_list_swap_tree(struct tcl_list* tcl, struct tcl_list* data) +{ + /* swap tree and region */ + rbtree_type oldtree = tcl->tree; + struct regional* oldregion = tcl->region; + tcl->tree = data->tree; + tcl->region = data->region; + data->tree = oldtree; + data->region = oldregion; +} diff --git a/util/tcp_conn_limit.h b/util/tcp_conn_limit.h index 4fb71a328036..52108942c7c4 100644 --- a/util/tcp_conn_limit.h +++ b/util/tcp_conn_limit.h @@ -127,4 +127,13 @@ tcl_addr_lookup(struct tcl_list* tcl, struct sockaddr_storage* addr, */ size_t tcl_list_get_mem(struct tcl_list* tcl); +/** + * Swap internal tree with preallocated entries. Caller should manage + * tcl_addr item locks. + * @param tcl: the tcp connection list structure. + * @param data: the data structure used to take elements from. This contains + * the old elements on return. + */ +void tcl_list_swap_tree(struct tcl_list* tcl, struct tcl_list* data); + #endif /* DAEMON_TCP_CONN_LIMIT_H */ diff --git a/util/tube.c b/util/tube.c index 7d98b93c3751..96187e134e2f 100644 --- a/util/tube.c +++ b/util/tube.c @@ -584,7 +584,10 @@ void tube_close_write(struct tube* ATTR_UNUSED(tube)) void tube_remove_bg_listen(struct tube* tube) { verbose(VERB_ALGO, "tube remove_bg_listen"); - ub_winsock_unregister_wsaevent(tube->ev_listen); + if (tube->ev_listen != NULL) { + ub_winsock_unregister_wsaevent(tube->ev_listen); + tube->ev_listen = NULL; + } } void tube_remove_bg_write(struct tube* tube) diff --git a/util/ub_event.c b/util/ub_event.c index 8cd87ec4e1d4..9133d446cbd3 100644 --- a/util/ub_event.c +++ b/util/ub_event.c @@ -46,6 +46,13 @@ #include "util/log.h" #include "util/netevent.h" #include "util/tube.h" +#include "daemon/remote.h" +#ifdef USE_DNSTAP +#include "dnstap/dtstream.h" +#endif +#ifdef UB_ON_WINDOWS +#include "winrc/win_svc.h" +#endif /* We define libevent structures here to hide the libevent stuff. */ @@ -95,9 +102,29 @@ UB_EV_BITS_CB(comm_timer_callback) UB_EV_BITS_CB(comm_signal_callback) UB_EV_BITS_CB(comm_point_local_handle_callback) UB_EV_BITS_CB(comm_point_raw_handle_callback) -UB_EV_BITS_CB(comm_point_http_handle_callback) UB_EV_BITS_CB(tube_handle_signal) UB_EV_BITS_CB(comm_base_handle_slow_accept) +UB_EV_BITS_CB(comm_point_http_handle_callback) +#ifdef HAVE_NGTCP2 +UB_EV_BITS_CB(comm_point_doq_callback) +#endif +UB_EV_BITS_CB(fast_reload_service_cb) +#ifdef USE_DNSTAP +UB_EV_BITS_CB(dtio_output_cb) +UB_EV_BITS_CB(dtio_cmd_cb) +UB_EV_BITS_CB(dtio_reconnect_timeout_cb) +UB_EV_BITS_CB(dtio_stop_timer_cb) +UB_EV_BITS_CB(dtio_stop_ev_cb) +UB_EV_BITS_CB(dtio_tap_callback) +UB_EV_BITS_CB(dtio_mainfdcallback) +#endif +#ifdef HAVE_NGTCP2 +UB_EV_BITS_CB(doq_client_event_cb) +UB_EV_BITS_CB(doq_client_timer_cb) +#endif +#ifdef UB_ON_WINDOWS +UB_EV_BITS_CB(worker_win_stop_cb) +#endif static void (*NATIVE_BITS_CB(void (*cb)(int, short, void*)))(int, short, void*) { @@ -123,6 +150,38 @@ static void (*NATIVE_BITS_CB(void (*cb)(int, short, void*)))(int, short, void*) return my_tube_handle_signal; else if(cb == comm_base_handle_slow_accept) return my_comm_base_handle_slow_accept; +#ifdef HAVE_NGTCP2 + else if(cb == comm_point_doq_callback) + return my_comm_point_doq_callback; +#endif + else if(cb == fast_reload_service_cb) + return my_fast_reload_service_cb; +#ifdef USE_DNSTAP + else if(cb == dtio_output_cb) + return my_dtio_output_cb; + else if(cb == dtio_cmd_cb) + return my_dtio_cmd_cb; + else if(cb == dtio_reconnect_timeout_cb) + return my_dtio_reconnect_timeout_cb; + else if(cb == dtio_stop_timer_cb) + return my_dtio_stop_timer_cb; + else if(cb == dtio_stop_ev_cb) + return my_dtio_stop_ev_cb; + else if(cb == dtio_tap_callback) + return my_dtio_tap_callback; + else if(cb == dtio_mainfdcallback) + return my_dtio_mainfdcallback; +#endif +#ifdef HAVE_NGTCP2 + else if(cb == doq_client_event_cb) + return my_doq_client_event_cb; + else if(cb == doq_client_timer_cb) + return my_doq_client_timer_cb; +#endif +#ifdef UB_ON_WINDOWS + else if(cb == worker_win_stop_cb) + return my_worker_win_stop_cb; +#endif else { log_assert(0); /* this NULL callback pointer should not happen, we should have the necessary routine listed above */ diff --git a/validator/autotrust.c b/validator/autotrust.c index 36cdf3e0a7a2..a0f61885f5dd 100644 --- a/validator/autotrust.c +++ b/validator/autotrust.c @@ -353,7 +353,7 @@ autr_tp_create(struct val_anchors* anchors, uint8_t* own, size_t own_len, lock_basic_lock(&anchors->lock); if(!rbtree_insert(anchors->tree, &tp->node)) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; lock_basic_unlock(&anchors->lock); dname_str(tp->name, buf); log_err("trust anchor for '%s' presented twice", buf); @@ -363,7 +363,7 @@ autr_tp_create(struct val_anchors* anchors, uint8_t* own, size_t own_len, return NULL; } if(!rbtree_insert(&anchors->autr->probe, &tp->autr->pnode)) { - char buf[LDNS_MAX_DOMAINLEN+1]; + char buf[LDNS_MAX_DOMAINLEN]; (void)rbtree_delete(anchors->tree, tp); lock_basic_unlock(&anchors->lock); dname_str(tp->name, buf); @@ -2035,25 +2035,40 @@ wait_probe_time(struct val_anchors* anchors) return 0; } -/** reset worker timer */ +/** reset worker timer, at the time from wait_probe_time. */ static void -reset_worker_timer(struct module_env* env) +reset_worker_timer_at(struct module_env* env, time_t next) { struct timeval tv; #ifndef S_SPLINT_S - time_t next = (time_t)wait_probe_time(env->anchors); /* in case this is libunbound, no timer */ if(!env->probe_timer) return; if(next > *env->now) tv.tv_sec = (time_t)(next - *env->now); else tv.tv_sec = 0; +#else + (void)next; #endif tv.tv_usec = 0; comm_timer_set(env->probe_timer, &tv); verbose(VERB_ALGO, "scheduled next probe in " ARG_LL "d sec", (long long)tv.tv_sec); } +/** reset worker timer. This routine manages the locks on acquiring the + * next time for the timer. */ +static void +reset_worker_timer(struct module_env* env) +{ + time_t next; + if(!env->anchors) + return; + lock_basic_lock(&env->anchors->lock); + next = wait_probe_time(env->anchors); + lock_basic_unlock(&env->anchors->lock); + reset_worker_timer_at(env, next); +} + /** set next probe for trust anchor */ static int set_next_probe(struct module_env* env, struct trust_anchor* tp, @@ -2092,7 +2107,7 @@ set_next_probe(struct module_env* env, struct trust_anchor* tp, verbose(VERB_ALGO, "next probe set in %d seconds", (int)tp->autr->next_probe_time - (int)*env->now); if(mold != mnew) { - reset_worker_timer(env); + reset_worker_timer_at(env, mnew); } return 1; } @@ -2147,7 +2162,7 @@ autr_tp_remove(struct module_env* env, struct trust_anchor* tp, autr_point_delete(del_tp); } if(mold != mnew) { - reset_worker_timer(env); + reset_worker_timer_at(env, mnew); } } @@ -2288,7 +2303,9 @@ static void autr_debug_print_tp(struct trust_anchor* tp) { struct autr_ta* ta; - char buf[257]; + /* Note: buf is also used for autr_ctime_r but that only needs a size + * of 26, so LDNS_MAX_DOMAINLEN is enough. */ + char buf[LDNS_MAX_DOMAINLEN]; if(!tp->autr) return; dname_str(tp->name, buf); diff --git a/validator/val_anchor.c b/validator/val_anchor.c index 8466a8923eb1..daa04504e595 100644 --- a/validator/val_anchor.c +++ b/validator/val_anchor.c @@ -483,11 +483,10 @@ anchor_read_file(struct val_anchors* anchors, sldns_buffer* buffer, /** skip file to end of line */ static void -skip_to_eol(FILE* in) +skip_to_eol(FILE* in, int *c) { - int c; - while((c = getc(in)) != EOF ) { - if(c == '\n') + while((*c = getc(in)) != EOF ) { + if(*c == '\n') return; } } @@ -534,7 +533,8 @@ readkeyword_bindfile(FILE* in, sldns_buffer* buf, int* line, int comments) int numdone = 0; while((c = getc(in)) != EOF ) { if(comments && c == '#') { /* # blabla */ - skip_to_eol(in); + skip_to_eol(in, &c); + if(c == EOF) return 0; (*line)++; continue; } else if(comments && c=='/' && numdone>0 && /* /_/ bla*/ @@ -542,7 +542,8 @@ readkeyword_bindfile(FILE* in, sldns_buffer* buf, int* line, int comments) sldns_buffer_position(buf)-1) == '/') { sldns_buffer_skip(buf, -1); numdone--; - skip_to_eol(in); + skip_to_eol(in, &c); + if(c == EOF) return 0; (*line)++; continue; } else if(comments && c=='*' && numdone>0 && /* /_* bla *_/ */ @@ -559,6 +560,7 @@ readkeyword_bindfile(FILE* in, sldns_buffer* buf, int* line, int comments) if(c == '\n') (*line)++; } + if(c == EOF) return 0; continue; } /* not a comment, complete the keyword */ @@ -593,6 +595,7 @@ readkeyword_bindfile(FILE* in, sldns_buffer* buf, int* line, int comments) break; } } + if(c == EOF) return 0; return numdone; } if(is_bind_special(c)) @@ -1018,7 +1021,7 @@ anchors_assemble_rrsets(struct val_anchors* anchors) ta->name, LDNS_RR_TYPE_DNSKEY, ta->dclass); } if(nods == ta->numDS && nokey == ta->numDNSKEY) { - char b[257]; + char b[LDNS_MAX_DOMAINLEN]; dname_str(ta->name, b); log_warn("trust anchor %s has no supported algorithms," " the anchor is ignored (check if you need to" @@ -1170,17 +1173,53 @@ anchors_lookup(struct val_anchors* anchors, return result; } +/** Get memory usage of assembled key rrset */ +static size_t +assembled_rrset_get_mem(struct ub_packed_rrset_key* pkey) +{ + size_t s; + if(!pkey) + return 0; + s = sizeof(*pkey) + pkey->rk.dname_len; + if(pkey->entry.data) { + struct packed_rrset_data* pd = (struct packed_rrset_data*) + pkey->entry.data; + s += sizeof(*pd) + pd->count * (sizeof(size_t)+sizeof(time_t)+ + sizeof(uint8_t*)); + } + return s; +} + size_t anchors_get_mem(struct val_anchors* anchors) { struct trust_anchor *ta; - size_t s = sizeof(*anchors); - if(!anchors) - return 0; + struct ta_key *k; + size_t s; + if(!anchors) return 0; + s = sizeof(*anchors); + lock_basic_lock(&anchors->lock); RBTREE_FOR(ta, struct trust_anchor*, anchors->tree) { + lock_basic_lock(&ta->lock); s += sizeof(*ta) + ta->namelen; /* keys and so on */ + for(k = ta->keylist; k; k = k->next) { + s += sizeof(*k) + k->len; + } + s += assembled_rrset_get_mem(ta->ds_rrset); + s += assembled_rrset_get_mem(ta->dnskey_rrset); + if(ta->autr) { + struct autr_ta* p; + s += sizeof(*ta->autr); + if(ta->autr->file) + s += strlen(ta->autr->file); + for(p = ta->autr->keys; p; p=p->next) { + s += sizeof(*p) + p->rr_len; + } + } + lock_basic_unlock(&ta->lock); } + lock_basic_unlock(&anchors->lock); return s; } @@ -1343,3 +1382,22 @@ anchors_find_any_noninsecure(struct val_anchors* anchors) lock_basic_unlock(&anchors->lock); return NULL; } + +void +anchors_swap_tree(struct val_anchors* anchors, struct val_anchors* data) +{ + rbtree_type* oldtree; + rbtree_type oldprobe; + + if(!anchors || !data) + return; /* If anchors is NULL, there is no validation. */ + + oldtree = anchors->tree; + oldprobe = anchors->autr->probe; + + anchors->tree = data->tree; + anchors->autr->probe = data->autr->probe; + + data->tree = oldtree; + data->autr->probe = oldprobe; +} diff --git a/validator/val_anchor.h b/validator/val_anchor.h index 02e7e17b5210..3fcf70eec920 100644 --- a/validator/val_anchor.h +++ b/validator/val_anchor.h @@ -58,7 +58,7 @@ struct sldns_buffer; * on a trust anchor and look it up again to delete it. */ struct val_anchors { - /** lock on trees */ + /** lock on trees. It is locked in order after stubs. */ lock_basic_type lock; /** * Anchors are store in this tree. Sort order is chosen, so that @@ -248,4 +248,12 @@ int anchor_has_keytag(struct val_anchors* anchors, uint8_t* name, int namelabs, */ struct trust_anchor* anchors_find_any_noninsecure(struct val_anchors* anchors); +/** + * Swap internal tree with preallocated entries. + * @param anchors: anchor storage. + * @param data: the data structure used to take elements from. This contains + * the old elements on return. + */ +void anchors_swap_tree(struct val_anchors* anchors, struct val_anchors* data); + #endif /* VALIDATOR_VAL_ANCHOR_H */ diff --git a/validator/val_neg.c b/validator/val_neg.c index b5b678fdea68..bc3a83aeb4c9 100644 --- a/validator/val_neg.c +++ b/validator/val_neg.c @@ -1554,3 +1554,12 @@ val_neg_getmsg(struct val_neg_cache* neg, struct query_info* qinfo, lock_basic_unlock(&neg->lock); return msg; } + +void +val_neg_adjust_size(struct val_neg_cache* neg, size_t max) +{ + lock_basic_lock(&neg->lock); + neg->max = max; + neg_make_space(neg, 0); + lock_basic_unlock(&neg->lock); +} diff --git a/validator/val_neg.h b/validator/val_neg.h index 5643ca3314a7..27617dee5a1c 100644 --- a/validator/val_neg.h +++ b/validator/val_neg.h @@ -299,4 +299,11 @@ struct val_neg_zone* neg_create_zone(struct val_neg_cache* neg, */ void val_neg_zone_take_inuse(struct val_neg_zone* zone); +/** + * Adjust the size of the negative cache. + * @param neg: negative cache + * @param max: new size for max mem. + */ +void val_neg_adjust_size(struct val_neg_cache* neg, size_t max); + #endif /* VALIDATOR_VAL_NEG_H */ diff --git a/validator/validator.c b/validator/validator.c index 857510b655e7..a0550b484eae 100644 --- a/validator/validator.c +++ b/validator/validator.c @@ -91,50 +91,98 @@ update_reason_bogus(struct reply_info* rep, sldns_ede_code reason_bogus) /** fill up nsec3 key iterations config entry */ static int -fill_nsec3_iter(struct val_env* ve, char* s, int c) +fill_nsec3_iter(size_t** keysize, size_t** maxiter, char* s, int c) { char* e; int i; - free(ve->nsec3_keysize); - free(ve->nsec3_maxiter); - ve->nsec3_keysize = (size_t*)calloc((size_t)c, sizeof(size_t)); - ve->nsec3_maxiter = (size_t*)calloc((size_t)c, sizeof(size_t)); - if(!ve->nsec3_keysize || !ve->nsec3_maxiter) { + *keysize = (size_t*)calloc((size_t)c, sizeof(size_t)); + *maxiter = (size_t*)calloc((size_t)c, sizeof(size_t)); + if(!*keysize || !*maxiter) { + free(*keysize); + *keysize = NULL; + free(*maxiter); + *maxiter = NULL; log_err("out of memory"); return 0; } for(i=0; i<c; i++) { - ve->nsec3_keysize[i] = (size_t)strtol(s, &e, 10); + (*keysize)[i] = (size_t)strtol(s, &e, 10); if(s == e) { log_err("cannot parse: %s", s); + free(*keysize); + *keysize = NULL; + free(*maxiter); + *maxiter = NULL; return 0; } s = e; - ve->nsec3_maxiter[i] = (size_t)strtol(s, &e, 10); + (*maxiter)[i] = (size_t)strtol(s, &e, 10); if(s == e) { log_err("cannot parse: %s", s); + free(*keysize); + *keysize = NULL; + free(*maxiter); + *maxiter = NULL; return 0; } s = e; - if(i>0 && ve->nsec3_keysize[i-1] >= ve->nsec3_keysize[i]) { + if(i>0 && (*keysize)[i-1] >= (*keysize)[i]) { log_err("nsec3 key iterations not ascending: %d %d", - (int)ve->nsec3_keysize[i-1], - (int)ve->nsec3_keysize[i]); + (int)(*keysize)[i-1], (int)(*keysize)[i]); + free(*keysize); + *keysize = NULL; + free(*maxiter); + *maxiter = NULL; return 0; } verbose(VERB_ALGO, "validator nsec3cfg keysz %d mxiter %d", - (int)ve->nsec3_keysize[i], (int)ve->nsec3_maxiter[i]); + (int)(*keysize)[i], (int)(*maxiter)[i]); } return 1; } +int +val_env_parse_key_iter(char* val_nsec3_key_iterations, size_t** keysize, + size_t** maxiter, int* keyiter_count) +{ + int c; + c = cfg_count_numbers(val_nsec3_key_iterations); + if(c < 1 || (c&1)) { + log_err("validator: unparsable or odd nsec3 key " + "iterations: %s", val_nsec3_key_iterations); + return 0; + } + *keyiter_count = c/2; + if(!fill_nsec3_iter(keysize, maxiter, val_nsec3_key_iterations, c/2)) { + log_err("validator: cannot apply nsec3 key iterations"); + return 0; + } + return 1; +} + +void +val_env_apply_cfg(struct val_env* val_env, struct config_file* cfg, + size_t* keysize, size_t* maxiter, int keyiter_count) +{ + free(val_env->nsec3_keysize); + free(val_env->nsec3_maxiter); + val_env->nsec3_keysize = keysize; + val_env->nsec3_maxiter = maxiter; + val_env->nsec3_keyiter_count = keyiter_count; + val_env->bogus_ttl = (uint32_t)cfg->bogus_ttl; + val_env->date_override = cfg->val_date_override; + val_env->skew_min = cfg->val_sig_skew_min; + val_env->skew_max = cfg->val_sig_skew_max; + val_env->max_restart = cfg->val_max_restart; +} + /** apply config settings to validator */ static int val_apply_cfg(struct module_env* env, struct val_env* val_env, struct config_file* cfg) { - int c; - val_env->bogus_ttl = (uint32_t)cfg->bogus_ttl; + size_t* keysize=NULL, *maxiter=NULL; + int keyiter_count = 0; if(!env->anchors) env->anchors = anchors_create(); if(!env->anchors) { @@ -154,21 +202,11 @@ val_apply_cfg(struct module_env* env, struct val_env* val_env, log_err("validator: error in trustanchors config"); return 0; } - val_env->date_override = cfg->val_date_override; - val_env->skew_min = cfg->val_sig_skew_min; - val_env->skew_max = cfg->val_sig_skew_max; - val_env->max_restart = cfg->val_max_restart; - c = cfg_count_numbers(cfg->val_nsec3_key_iterations); - if(c < 1 || (c&1)) { - log_err("validator: unparsable or odd nsec3 key " - "iterations: %s", cfg->val_nsec3_key_iterations); - return 0; - } - val_env->nsec3_keyiter_count = c/2; - if(!fill_nsec3_iter(val_env, cfg->val_nsec3_key_iterations, c/2)) { - log_err("validator: cannot apply nsec3 key iterations"); + if(!val_env_parse_key_iter(cfg->val_nsec3_key_iterations, + &keysize, &maxiter, &keyiter_count)) { return 0; } + val_env_apply_cfg(val_env, cfg, keysize, maxiter, keyiter_count); if (env->neg_cache) val_env->neg_cache = env->neg_cache; if(!val_env->neg_cache) @@ -210,7 +248,7 @@ val_init(struct module_env* env, int id) struct trust_anchor* anchor = anchors_find_any_noninsecure( env->anchors); if(anchor) { - char b[LDNS_MAX_DOMAINLEN+2]; + char b[LDNS_MAX_DOMAINLEN]; dname_str(anchor->name, b); log_warn("validator: disable-edns-do is enabled, but there is a trust anchor for '%s'. Since DNSSEC could not work, the disable-edns-do setting is turned off. Continuing without it.", b); lock_basic_unlock(&anchor->lock); @@ -2563,7 +2601,7 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq, if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo, vq->orig_msg->rep, 0, qstate->prefetch_leeway, 0, qstate->region, qstate->query_flags, - qstate->qstarttime)) { + qstate->qstarttime, qstate->is_valrec)) { log_err("out of memory caching validator results"); } } @@ -2572,7 +2610,8 @@ processFinished(struct module_qstate* qstate, struct val_qstate* vq, /* and this does not get prefetched, so no leeway */ if(!dns_cache_store(qstate->env, &vq->orig_msg->qinfo, vq->orig_msg->rep, 1, 0, 0, qstate->region, - qstate->query_flags, qstate->qstarttime)) { + qstate->query_flags, qstate->qstarttime, + qstate->is_valrec)) { log_err("out of memory caching validator results"); } } diff --git a/validator/validator.h b/validator/validator.h index c07f9d59d90d..e04fad572770 100644 --- a/validator/validator.h +++ b/validator/validator.h @@ -52,6 +52,7 @@ struct key_entry_key; struct val_neg_cache; struct config_strlist; struct comm_timer; +struct config_file; /** * This is the TTL to use when a trust anchor fails to prime. A trust anchor @@ -280,4 +281,26 @@ size_t val_get_mem(struct module_env* env, int id); /** Timer callback for msg signatures continue timer */ void validate_suspend_timer_cb(void* arg); +/** + * Parse the val_nsec3_key_iterations string. + * @param val_nsec3_key_iterations: the string with nsec3 iterations config. + * @param keysize: returns malloced key size array on success. + * @param maxiter: returns malloced max iterations array on success. + * @param keyiter_count: returns size of keysize and maxiter arrays. + * @return false if it does not parse correctly. + */ +int val_env_parse_key_iter(char* val_nsec3_key_iterations, size_t** keysize, + size_t** maxiter, int* keyiter_count); + +/** + * Apply config to validator env + * @param val_env: validator env. + * @param cfg: config + * @param keysize: nsec3 key size array. + * @param maxiter: nsec3 max iterations array. + * @param keyiter_count: size of keysize and maxiter arrays. + */ +void val_env_apply_cfg(struct val_env* val_env, struct config_file* cfg, + size_t* keysize, size_t* maxiter, int keyiter_count); + #endif /* VALIDATOR_VALIDATOR_H */ diff --git a/winrc/win_svc.c b/winrc/win_svc.c index 49d4251fa260..40e12f1cff87 100644 --- a/winrc/win_svc.c +++ b/winrc/win_svc.c @@ -363,11 +363,36 @@ service_init(int r, struct daemon** d, struct config_file** c) return 0; } if(cfg->ssl_service_key && cfg->ssl_service_key[0]) { - if(!(daemon->listen_sslctx = listen_sslctx_create( - cfg->ssl_service_key, cfg->ssl_service_pem, NULL))) + if(!(daemon->listen_dot_sslctx = listen_sslctx_create( + cfg->ssl_service_key, cfg->ssl_service_pem, NULL, + cfg->tls_ciphers, cfg->tls_ciphersuites, + (cfg->tls_session_ticket_keys.first && + cfg->tls_session_ticket_keys.first->str[0] != 0), + 1, 0))) { fatal_exit("could not set up listen SSL_CTX"); + } +#ifdef HAVE_NGHTTP2_NGHTTP2_H + if(cfg_has_https(cfg)) { + if(!(daemon->listen_doh_sslctx = listen_sslctx_create( + cfg->ssl_service_key, cfg->ssl_service_pem, NULL, + cfg->tls_ciphers, cfg->tls_ciphersuites, + (cfg->tls_session_ticket_keys.first && + cfg->tls_session_ticket_keys.first->str[0] != 0), + 0, 1))) { + fatal_exit("could not set up listen doh SSL_CTX"); + } + } +#endif +#ifdef HAVE_NGTCP2 + if(cfg_has_quic(cfg)) { + if(!(daemon->listen_quic_sslctx = quic_sslctx_create( + cfg->ssl_service_key, cfg->ssl_service_pem, NULL))) { + fatal_exit("could not set up quic SSL_CTX"); + } + } +#endif /* HAVE_NGTCP2 */ } - if(!(daemon->connect_sslctx = connect_sslctx_create(NULL, NULL, + if(!(daemon->connect_dot_sslctx = connect_sslctx_create(NULL, NULL, cfg->tls_cert_bundle, cfg->tls_win_cert))) fatal_exit("could not set up connect SSL_CTX"); |