untrusted comment: verify with openbsd-78-base.pub RWS3/nvFmk4SWfJOjGub3zngZigiB4W/703DzBCxVWR3ReABpG+qYuQh0Ivf+0haxfa1SDZbrqsXeYHb3e6vc8SCMweicPgV9gw= OpenBSD 7.8 errata 059, September 30, 2026: Update unbound(8) to version 1.26.1. CVE-2026-14586 CVE-2026-32665 CVE-2026-32792 CVE-2026-33278 CVE-2026-40622 CVE-2026-40691 CVE-2026-41292 CVE-2026-41637 CVE-2026-42534 CVE-2026-42923 CVE-2026-42944 CVE-2026-42955 CVE-2026-42959 CVE-2026-42960 CVE-2026-44390 CVE-2026-44608 CVE-2026-44621 CVE-2026-44687 CVE-2026-44690 CVE-2026-46582 CVE-2026-50045 CVE-2026-50046 CVE-2026-50243 CVE-2026-50248 CVE-2026-50251 CVE-2026-50252 CVE-2026-52863 CVE-2026-54478 CVE-2026-55708 CVE-2026-55717 CVE-2026-55973 CVE-2026-55990 CVE-2026-55991 CVE-2026-56416 CVE-2026-56444 Apply by doing: signify -Vep /etc/signify/openbsd-78-base.pub -x 059_unbound.patch.sig \ -m - | (cd /usr/src && patch -p0) And then rebuild and install unwind and unbound: cd /usr/src/sbin/unwind make obj make make install cd /usr/src/usr.sbin/unbound make -f Makefile.bsd-wrapper obj make -f Makefile.bsd-wrapper clean make -f Makefile.bsd-wrapper make -f Makefile.bsd-wrapper install Index: sbin/unwind/libunbound/config.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/config.h,v diff -u -p -r1.27 config.h --- sbin/unwind/libunbound/config.h 29 Sep 2025 14:53:38 -0000 1.27 +++ sbin/unwind/libunbound/config.h 21 Sep 2026 16:28:23 -0000 @@ -36,6 +36,9 @@ /* Whether daemon is deprecated */ /* #undef DEPRECATED_DAEMON */ +/* Whether X509_NAME_get_text_by_NID is deprecated */ +/* #undef DEPRECATED_X509_NAME_GET_TEXT_BY_NID */ + /* Deprecate RSA 1024 bit length, makes that an unsupported key */ /* #undef DEPRECATE_RSA_1024 */ @@ -65,12 +68,18 @@ /* Define to 1 if you have the header file. */ #define HAVE_ARPA_INET_H 1 +/* Define to 1 if you have the `ASN1_STRING_get0_data' function. */ +#define HAVE_ASN1_STRING_GET0_DATA 1 + /* Whether the C compiler accepts the "fallthrough" attribute */ #define HAVE_ATTR_FALLTHROUGH 1 /* Whether the C compiler accepts the "format" attribute */ #define HAVE_ATTR_FORMAT 1 +/* Whether the C compiler accepts the "nonstring" attribute */ +#define HAVE_ATTR_NONSTRING 1 + /* Whether the C compiler accepts the "noreturn" attribute */ #define HAVE_ATTR_NORETURN 1 @@ -142,6 +151,10 @@ to 0 if you don't. */ /* #undef HAVE_DECL_NGTCP2_CRYPTO_ENCRYPT_CB */ +/* Define to 1 if you have the declaration of `ngtcp2_crypto_ossl_ctx_new', + and to 0 if you don't. */ +/* #undef HAVE_DECL_NGTCP2_CRYPTO_OSSL_CTX_NEW */ + /* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you don't. */ #define HAVE_DECL_NID_ED25519 1 @@ -291,6 +304,12 @@ /* Define to 1 if you have the `FIPS_mode' function. */ #define HAVE_FIPS_MODE 1 +/* Define to 1 if you have the `fnmatch' function. */ +#define HAVE_FNMATCH 1 + +/* Define to 1 if you have the header file. */ +#define HAVE_FNMATCH_H 1 + /* Define to 1 if you have the `fork' function. */ #define HAVE_FORK 1 @@ -515,6 +534,9 @@ /* Define to 1 if you have the header file. */ #define HAVE_OPENSSL_BN_H 1 +/* Define to 1 if you have the `OPENSSL_cleanup' function. */ +#define HAVE_OPENSSL_CLEANUP 1 + /* Define to 1 if you have the `OPENSSL_config' function. */ #define HAVE_OPENSSL_CONFIG 1 @@ -566,12 +588,27 @@ /* Define if you have POSIX threads libraries and header files. */ /* #undef HAVE_PTHREAD */ +/* Define to 1 if you have the header file. */ +/* #undef HAVE_PTHREAD_NP_H */ + /* Have PTHREAD_PRIO_INHERIT. */ /* #undef HAVE_PTHREAD_PRIO_INHERIT */ /* Define to 1 if the system has the type `pthread_rwlock_t'. */ /* #undef HAVE_PTHREAD_RWLOCK_T */ +/* Define if pthread_setname_np has the common 2 arguments. */ +/* #undef HAVE_PTHREAD_SETNAME_NP */ + +/* Define if pthread_setname_np has only 1 argument. */ +/* #undef HAVE_PTHREAD_SETNAME_NP1 */ + +/* Define if pthread_setname_np has 3 arguments. */ +/* #undef HAVE_PTHREAD_SETNAME_NP3 */ + +/* Define if pthread_setname_np exists as pthread_set_name_np instead. */ +/* #undef HAVE_PTHREAD_SET_NAME_NP */ + /* Define to 1 if the system has the type `pthread_spinlock_t'. */ /* #undef HAVE_PTHREAD_SPINLOCK_T */ @@ -672,9 +709,16 @@ /* Define to 1 if you have the `SSL_is_quic' function. */ /* #undef HAVE_SSL_IS_QUIC */ +/* Define to 1 if you have the `SSL_set1_dnsname' function. */ +/* #undef HAVE_SSL_SET1_DNSNAME */ + /* Define to 1 if you have the `SSL_set1_host' function. */ #define HAVE_SSL_SET1_HOST 1 +/* Define to 1 if you have the `SSL_set_quic_tls_early_data_enabled' function. + */ +/* #undef HAVE_SSL_SET_QUIC_TLS_EARLY_DATA_ENABLED */ + /* Define to 1 if you have the header file. */ #define HAVE_STDARG_H 1 @@ -737,6 +781,12 @@ /* Define to 1 if `sun_len' is a member of `struct sockaddr_un'. */ #define HAVE_STRUCT_SOCKADDR_UN_SUN_LEN 1 +/* Define to 1 if `st_mtimensec' is a member of `struct stat'. */ +#define HAVE_STRUCT_STAT_ST_MTIMENSEC 1 + +/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */ +#define HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1 + /* Define if you have Swig libraries and header files. */ /* #undef HAVE_SWIG */ @@ -833,6 +883,12 @@ /* Define to 1 if you have the header file. */ /* #undef HAVE_WS2TCPIP_H */ +/* Define to 1 if you have the `X509_get_key_usage' function. */ +#define HAVE_X509_GET_KEY_USAGE 1 + +/* Define to 1 if you have the `X509_NAME_get_text_by_NID' function. */ +#define HAVE_X509_NAME_GET_TEXT_BY_NID 1 + /* Define to 1 if you have the `X509_VERIFY_PARAM_set1_host' function. */ #define HAVE_X509_VERIFY_PARAM_SET1_HOST 1 @@ -895,7 +951,7 @@ #define PACKAGE_NAME "unbound" /* Define to the full name and version of this package. */ -#define PACKAGE_STRING "unbound 1.24.0" +#define PACKAGE_STRING "unbound 1.26.1" /* Define to the one symbol short name of this package. */ #define PACKAGE_TARNAME "unbound" @@ -904,7 +960,7 @@ #define PACKAGE_URL "" /* Define to the version of this package. */ -#define PACKAGE_VERSION "1.24.0" +#define PACKAGE_VERSION "1.26.1" /* default pidfile location */ #define PIDFILE "" @@ -927,7 +983,7 @@ #define ROOT_CERT_FILE "/var/unbound/etc/icannbundle.pem" /* version number for resource files */ -#define RSRC_PACKAGE_VERSION 1,24,0,0 +#define RSRC_PACKAGE_VERSION 1,26,1,0 /* Directory to chdir to */ #define RUN_DIR "/var/unbound/etc" @@ -1384,6 +1440,17 @@ #else /* !HAVE_ATTR_UNUSED */ # define ATTR_UNUSED(x) x #endif /* !HAVE_ATTR_UNUSED */ + + +#if defined(DOXYGEN) +# define ATTR_NONSTRING(x) x +#elif defined(__cplusplus) +# define ATTR_NONSTRING(x) __attribute__((nonstring)) x +#elif defined(HAVE_ATTR_NONSTRING) +# define ATTR_NONSTRING(x) __attribute__((nonstring)) x +#else /* !HAVE_ATTR_NONSTRING */ +# define ATTR_NONSTRING(x) x +#endif /* !HAVE_ATTR_NONSTRING */ #ifndef HAVE_FSEEKO Index: sbin/unwind/libunbound/daemon/remote.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/daemon/remote.h,v diff -u -p -r1.1 remote.h --- sbin/unwind/libunbound/daemon/remote.h 14 Sep 2025 15:16:53 -0000 1.1 +++ sbin/unwind/libunbound/daemon/remote.h 21 Sep 2026 16:28:23 -0000 @@ -49,6 +49,26 @@ #include #endif #include "util/locks.h" + +struct comm_reply; +struct comm_point; + +/** 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); + +/** handle remote control accept callbacks */ +int remote_accept_callback(struct comm_point*, void*, int, struct comm_reply*); + +/** handle remote control data callbacks */ +int remote_control_callback(struct comm_point*, void*, int, struct comm_reply*); + +/** routine to printout option values over SSL */ +void remote_get_opt_ssl(char* line, void* arg); + struct config_file; struct listen_list; struct listen_port; @@ -206,6 +226,12 @@ struct fast_reload_thread { int commpair[2]; /** thread id, of the io thread */ ub_thread_type tid; +#ifdef HAVE_GETTID + /** thread tid, the LWP id */ + pid_t thread_tid; + /** if logging should include the LWP id */ + int thread_tid_log; +#endif /** if the io processing has started */ int started; /** if the thread has to quit */ @@ -249,6 +275,8 @@ struct fast_reload_thread { struct fast_reload_auth_change* auth_zone_change_list; /** the old tree of auth zones, to lookup. */ struct auth_zones* old_auth_zones; + /** If the ssl ctxs have changed. */ + int sslctxs_changed; }; /** Index: sbin/unwind/libunbound/daemon/worker.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/daemon/worker.h,v diff -u -p -r1.4 worker.h --- sbin/unwind/libunbound/daemon/worker.h 14 Sep 2025 15:16:53 -0000 1.4 +++ sbin/unwind/libunbound/daemon/worker.h 21 Sep 2026 16:28:23 -0000 @@ -104,10 +104,6 @@ struct worker { struct listen_dnsport* front; /** the backside outside network interface to the auth servers */ struct outside_network* back; - /** ports to be used by this worker. */ - int* ports; - /** number of ports for this worker */ - int numports; /** the signal handler */ struct comm_signal* comsig; /** commpoint to listen to commands. */ @@ -146,11 +142,9 @@ struct worker { * with backpointers only. Use worker_init on it later. * @param daemon: the daemon that this worker thread is part of. * @param id: the thread number from 0.. numthreads-1. - * @param ports: the ports it is allowed to use, array. - * @param n: the number of ports. * @return: the new worker or NULL on alloc failure. */ -struct worker* worker_create(struct daemon* daemon, int id, int* ports, int n); +struct worker* worker_create(struct daemon* daemon, int id); /** * Initialize worker. Index: sbin/unwind/libunbound/dns64/dns64.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/dns64/dns64.c,v diff -u -p -r1.13 dns64.c --- sbin/unwind/libunbound/dns64/dns64.c 29 Sep 2025 14:53:38 -0000 1.13 +++ sbin/unwind/libunbound/dns64/dns64.c 21 Sep 2026 16:28:23 -0000 @@ -366,22 +366,23 @@ static int dns64_apply_cfg(struct dns64_env* dns64_env, struct config_file* cfg) { struct config_strlist* s; - verbose(VERB_ALGO, "dns64-prefix: %s", cfg->dns64_prefix); - if (!netblockstrtoaddr(cfg->dns64_prefix ? cfg->dns64_prefix : - DEFAULT_DNS64_PREFIX, 0, &dns64_env->prefix_addr, + const char* dns64_prefix = cfg->dns64_prefix ? + cfg->dns64_prefix : DEFAULT_DNS64_PREFIX; + verbose(VERB_ALGO, "dns64-prefix: %s", dns64_prefix); + if (!netblockstrtoaddr(dns64_prefix, 0, &dns64_env->prefix_addr, &dns64_env->prefix_addrlen, &dns64_env->prefix_net)) { - log_err("cannot parse dns64-prefix netblock: %s", cfg->dns64_prefix); + log_err("cannot parse dns64-prefix netblock: %s", dns64_prefix); return 0; } if (!addr_is_ip6(&dns64_env->prefix_addr, dns64_env->prefix_addrlen)) { - log_err("dns64_prefix is not IPv6: %s", cfg->dns64_prefix); + log_err("dns64_prefix is not IPv6: %s", dns64_prefix); return 0; } if (dns64_env->prefix_net != 32 && dns64_env->prefix_net != 40 && dns64_env->prefix_net != 48 && dns64_env->prefix_net != 56 && dns64_env->prefix_net != 64 && dns64_env->prefix_net != 96 ) { - log_err("dns64-prefix length it not 32, 40, 48, 56, 64 or 96: %s", - cfg->dns64_prefix); + log_err("dns64-prefix length is not 32, 40, 48, 56, 64 or 96: %s", + dns64_prefix); return 0; } for(s = cfg->dns64_ignore_aaaa; s; s = s->next) { @@ -496,8 +497,8 @@ handle_ipv6_ptr(struct module_qstate* qs /* Create the new sub-query. */ fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); - if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0, 0, - &subq)) + if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->client_info, + qstate->query_flags, 0, 0, &subq)) return module_error; if (subq) { subq->curmod = id; @@ -522,8 +523,8 @@ generate_type_A_query(struct module_qsta /* Start the sub-query. */ fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); - if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->query_flags, 0, - 0, &subq)) + if(!(*qstate->env->attach_sub)(qstate, &qinfo, qstate->client_info, + qstate->query_flags, 0, 0, &subq)) { verbose(VERB_ALGO, "dns64: sub-query creation failed"); return module_error; @@ -642,6 +643,12 @@ handle_event_moddone(struct module_qstat qstate->return_msg->rep && reply_find_answer_rrset(&qstate->qinfo, qstate->return_msg->rep); int synth_qname = 0; + if(could_synth && !has_data && qstate->env->need_to_validate && + qstate->return_msg && qstate->return_msg->rep && + qstate->return_msg->rep->security == sec_status_bogus) { + verbose(VERB_ALGO, "dns64: bogus AAAA reply not synthesized"); + could_synth = 0; + } if(could_synth && (!has_data || @@ -653,8 +660,11 @@ handle_event_moddone(struct module_qstat /* Store the response in cache. */ if( (!iq || !iq->started_no_cache_store) && + !qstate->rpz_applied && !qstate->rpz_passthru && + !qstate->is_subnet_answer && qstate->return_msg && qstate->return_msg->rep && + !qstate->fwd_stub_no_cache && !dns_cache_store( qstate->env, &qstate->qinfo, qstate->return_msg->rep, 0, qstate->prefetch_leeway, 0, NULL, @@ -716,8 +726,15 @@ dns64_operate(struct module_qstate* qsta } if(qstate->ext_state[id] == module_finished) { iq = (struct dns64_qstate*)qstate->minfo[id]; - if(iq && iq->state != DNS64_INTERNAL_QUERY) - qstate->no_cache_store = iq->started_no_cache_store; + if(iq && iq->state != DNS64_INTERNAL_QUERY) { + if(qstate->fwd_stub_no_cache) { + /* If the forward/stub has no cache, then + * continue with the query with no cache. */ + qstate->no_cache_store = qstate->fwd_stub_no_cache; + } else { + qstate->no_cache_store = iq->started_no_cache_store; + } + } } } @@ -824,6 +841,7 @@ dns64_adjust_a(int id, struct module_qst size_t i, s; struct packed_rrset_data* fd, *dd; struct ub_packed_rrset_key* fk, *dk; + int allocated_return_msg = 0; verbose(VERB_ALGO, "converting A answers to AAAA answers"); @@ -839,6 +857,7 @@ dns64_adjust_a(int id, struct module_qst return; memset(super->return_msg, 0, sizeof(*super->return_msg)); super->return_msg->qinfo = super->qinfo; + allocated_return_msg = 1; } rep = qstate->return_msg->rep; @@ -851,11 +870,14 @@ dns64_adjust_a(int id, struct module_qst rep->serve_expired_norec_ttl, rep->an_numrrsets, rep->ns_numrrsets, rep->ar_numrrsets, rep->rrset_count, rep->security, LDNS_EDE_NONE); - if(!cp) + if(!cp) { + if(allocated_return_msg) super->return_msg = NULL; return; + } /* allocate ub_key structures special or not */ if(!reply_info_alloc_rrset_keys(cp, NULL, super->region)) { + if(allocated_return_msg) super->return_msg = NULL; return; } @@ -870,8 +892,10 @@ dns64_adjust_a(int id, struct module_qst if(ian_numrrsets && fk->rk.type == htons(LDNS_RR_TYPE_A)) { /* also sets dk->entry.hash */ dns64_synth_aaaa_data(fk, fd, dk, &dd, super->region, dns64_env); - if(!dd) + if(!dd) { + if(allocated_return_msg) super->return_msg = NULL; return; + } /* Delete negative AAAA record from cache stored by * the iterator module */ rrset_cache_remove(super->env->rrset_cache, dk->rk.dname, @@ -888,15 +912,19 @@ dns64_adjust_a(int id, struct module_qst dk->rk.dname = (uint8_t*)regional_alloc_init(super->region, fk->rk.dname, fk->rk.dname_len); - if(!dk->rk.dname) + if(!dk->rk.dname) { + if(allocated_return_msg) super->return_msg = NULL; return; + } s = packed_rrset_sizeof(fd); dd = (struct packed_rrset_data*)regional_alloc_init( super->region, fd, s); - if(!dd) + if(!dd) { + if(allocated_return_msg) super->return_msg = NULL; return; + } } packed_rrset_ptr_fixup(dd); @@ -927,8 +955,10 @@ dns64_adjust_ptr(struct module_qstate* q return; super->return_msg->qinfo = super->qinfo; if (!(super->return_msg->rep = reply_info_copy(qstate->return_msg->rep, - NULL, super->region))) + NULL, super->region))) { + super->return_msg = NULL; return; + } /* * Adjust the domain name of the answer RR set so that it matches the @@ -997,6 +1027,21 @@ dns64_inform_super(struct module_qstate* /* Use return code from A query in response to client. */ if (super->return_rcode != LDNS_RCODE_NOERROR) super->return_rcode = qstate->return_rcode; + /* RPZ applied to the subquery need to then change (not cache) + * the super query. With the super query not cached, it is + * going to run the state machine modules on incoming queries, + * that fetch the subquery (cache) response, and modify it + * according to the rpz policy. That makes the synthesized + * super query also adjusted by rpz policies. But loses cache + * hits. Even though the subquery likely is answered from cache, + * internally in its state machine process. */ + if(qstate->rpz_applied) + super->rpz_applied = 1; + if(qstate->rpz_passthru) + super->rpz_passthru = 1; + + /* Since the super qstate has a new response, its errinf is removed. */ + super->errinf = NULL; /* Generate a response suitable for the original query. */ if (qstate->qinfo.qtype == LDNS_RR_TYPE_A) { @@ -1005,9 +1050,16 @@ dns64_inform_super(struct module_qstate* log_assert(qstate->qinfo.qtype == LDNS_RR_TYPE_PTR); dns64_adjust_ptr(qstate, super); } + /* If the sub-query has no cache store, then also the super query. */ + if(qstate->fwd_stub_no_cache) + super->fwd_stub_no_cache = 1; /* Store the generated response in cache. */ - if ( (!super_dq || !super_dq->started_no_cache_store) && + if ( super->return_msg && super->return_msg->rep && + (!super_dq || !super_dq->started_no_cache_store) && + !qstate->fwd_stub_no_cache && + !super->rpz_applied && !super->rpz_passthru && + !super->is_subnet_answer && !dns_cache_store(super->env, &super->qinfo, super->return_msg->rep, 0, super->prefetch_leeway, 0, NULL, super->query_flags, qstate->qstarttime, qstate->is_valrec)) Index: sbin/unwind/libunbound/dnscrypt/dnscrypt.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/dnscrypt/dnscrypt.h,v diff -u -p -r1.2 dnscrypt.h --- sbin/unwind/libunbound/dnscrypt/dnscrypt.h 1 Mar 2022 18:34:21 -0000 1.2 +++ sbin/unwind/libunbound/dnscrypt/dnscrypt.h 21 Sep 2026 16:28:23 -0000 @@ -128,7 +128,8 @@ int dnsc_handle_curved_request(struct dn * \return 0 in case of failure. */ -int dnsc_handle_uncurved_request(struct comm_reply *repinfo); +int dnsc_handle_uncurved_request(struct comm_reply *repinfo, + struct sldns_buffer* buffer); /** * Computes the size of the shared secret cache entry. Index: sbin/unwind/libunbound/dnstap/dnstap.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/dnstap/dnstap.h,v diff -u -p -r1.8 dnstap.h --- sbin/unwind/libunbound/dnstap/dnstap.h 14 Sep 2025 15:16:53 -0000 1.8 +++ sbin/unwind/libunbound/dnstap/dnstap.h 21 Sep 2026 16:28:23 -0000 @@ -102,9 +102,9 @@ dt_create(struct config_file* cfg); * Apply config settings. * @param env: dnstap environment object. * @param cfg: new config settings. + * @return false on failure. */ -void -dt_apply_cfg(struct dt_env *env, struct config_file *cfg); +int dt_apply_cfg(struct dt_env *env, struct config_file *cfg); /** * Apply config settings for log enable for message types. Index: sbin/unwind/libunbound/iterator/iter_delegpt.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/iterator/iter_delegpt.c,v diff -u -p -r1.7 iter_delegpt.c --- sbin/unwind/libunbound/iterator/iter_delegpt.c 14 Sep 2025 15:16:53 -0000 1.7 +++ sbin/unwind/libunbound/iterator/iter_delegpt.c 21 Sep 2026 16:28:23 -0000 @@ -118,10 +118,10 @@ delegpt_add_ns(struct delegpt* dp, struc sizeof(struct delegpt_ns)); if(!ns) return 0; - ns->next = dp->nslist; ns->namelen = len; - dp->nslist = ns; ns->name = regional_alloc_init(region, name, ns->namelen); + if(!ns->name) + return 0; ns->cache_lookup_count = 0; ns->resolved = 0; ns->got4 = 0; @@ -137,7 +137,9 @@ delegpt_add_ns(struct delegpt* dp, struc } else { ns->tls_auth_name = NULL; } - return ns->name != 0; + ns->next = dp->nslist; + dp->nslist = ns; + return 1; } struct delegpt_ns* @@ -223,11 +225,7 @@ delegpt_add_addr(struct delegpt* dp, str sizeof(struct delegpt_addr)); if(!a) return 0; - a->next_target = dp->target_list; - dp->target_list = a; a->next_result = 0; - a->next_usable = dp->usable_list; - dp->usable_list = a; memcpy(&a->addr, addr, addrlen); a->addrlen = addrlen; a->attempts = 0; @@ -241,6 +239,10 @@ delegpt_add_addr(struct delegpt* dp, str } else { a->tls_auth_name = NULL; } + a->next_target = dp->target_list; + dp->target_list = a; + a->next_usable = dp->usable_list; + dp->usable_list = a; return 1; } @@ -398,30 +400,33 @@ delegpt_count_missing_targets(struct del /** find NS rrset in given list */ static struct ub_packed_rrset_key* -find_NS(struct reply_info* rep, size_t from, size_t to) +find_NS(struct reply_info* rep, size_t from, size_t to, uint16_t qclass) { size_t i; for(i=from; irrsets[i]->rk.type) == LDNS_RR_TYPE_NS) + if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NS && + ntohs(rep->rrsets[i]->rk.rrset_class) == qclass) return rep->rrsets[i]; } return NULL; } struct delegpt* -delegpt_from_message(struct dns_msg* msg, struct regional* region) +delegpt_from_message(struct dns_msg* msg, struct regional* region, int port) { struct ub_packed_rrset_key* ns_rrset = NULL; struct delegpt* dp; size_t i; /* look for NS records in the authority section... */ ns_rrset = find_NS(msg->rep, msg->rep->an_numrrsets, - msg->rep->an_numrrsets+msg->rep->ns_numrrsets); + msg->rep->an_numrrsets+msg->rep->ns_numrrsets, + msg->qinfo.qclass); /* In some cases (even legitimate, perfectly legal cases), the * NS set for the "referral" might be in the answer section. */ if(!ns_rrset) - ns_rrset = find_NS(msg->rep, 0, msg->rep->an_numrrsets); + ns_rrset = find_NS(msg->rep, 0, msg->rep->an_numrrsets, + msg->qinfo.qclass); /* If there was no NS rrset in the authority section, then this * wasn't a referral message. (It might not actually be a @@ -436,7 +441,7 @@ delegpt_from_message(struct dns_msg* msg dp->has_parent_side_NS = 1; /* created from message */ if(!delegpt_set_name(dp, region, ns_rrset->rk.dname)) return NULL; - if(!delegpt_rrset_add_ns(dp, region, ns_rrset, 0)) + if(!delegpt_rrset_add_ns(dp, region, ns_rrset, 0, port)) return NULL; /* add glue, A and AAAA in answer and additional section */ @@ -447,10 +452,12 @@ delegpt_from_message(struct dns_msg* msg i < (msg->rep->an_numrrsets+msg->rep->ns_numrrsets)) continue; - if(ntohs(s->rk.type) == LDNS_RR_TYPE_A) { + if(ntohs(s->rk.type) == LDNS_RR_TYPE_A && + ntohs(s->rk.rrset_class) == msg->qinfo.qclass) { if(!delegpt_add_rrset_A(dp, region, s, 0, NULL)) return NULL; - } else if(ntohs(s->rk.type) == LDNS_RR_TYPE_AAAA) { + } else if(ntohs(s->rk.type) == LDNS_RR_TYPE_AAAA && + ntohs(s->rk.rrset_class) == msg->qinfo.qclass) { if(!delegpt_add_rrset_AAAA(dp, region, s, 0, NULL)) return NULL; } @@ -460,7 +467,7 @@ delegpt_from_message(struct dns_msg* msg int delegpt_rrset_add_ns(struct delegpt* dp, struct regional* region, - struct ub_packed_rrset_key* ns_rrset, uint8_t lame) + struct ub_packed_rrset_key* ns_rrset, uint8_t lame, int port) { struct packed_rrset_data* nsdata = (struct packed_rrset_data*) ns_rrset->entry.data; @@ -475,7 +482,7 @@ delegpt_rrset_add_ns(struct delegpt* dp, continue; /* bad format */ /* add rdata of NS (= wirefmt dname), skip rdatalen bytes */ if(!delegpt_add_ns(dp, region, nsdata->rr_data[i]+2, lame, - NULL, UNBOUND_DNS_PORT)) + NULL, (port==-1?UNBOUND_DNS_PORT:port))) return 0; } return 1; @@ -534,7 +541,7 @@ delegpt_add_rrset(struct delegpt* dp, st if(!rrset) return 1; if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_NS) - return delegpt_rrset_add_ns(dp, region, rrset, lame); + return delegpt_rrset_add_ns(dp, region, rrset, lame, -1); else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_A) return delegpt_add_rrset_A(dp, region, rrset, lame, additions); else if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_AAAA) @@ -659,8 +666,6 @@ int delegpt_add_ns_mlc(struct delegpt* d free(ns); return 0; } - ns->next = dp->nslist; - dp->nslist = ns; ns->cache_lookup_count = 0; ns->resolved = 0; ns->got4 = 0; @@ -679,6 +684,8 @@ int delegpt_add_ns_mlc(struct delegpt* d } else { ns->tls_auth_name = NULL; } + ns->next = dp->nslist; + dp->nslist = ns; return 1; } @@ -704,11 +711,7 @@ int delegpt_add_addr_mlc(struct delegpt* a = (struct delegpt_addr*)malloc(sizeof(struct delegpt_addr)); if(!a) return 0; - a->next_target = dp->target_list; - dp->target_list = a; a->next_result = 0; - a->next_usable = dp->usable_list; - dp->usable_list = a; memcpy(&a->addr, addr, addrlen); a->addrlen = addrlen; a->attempts = 0; @@ -724,6 +727,10 @@ int delegpt_add_addr_mlc(struct delegpt* } else { a->tls_auth_name = NULL; } + a->next_target = dp->target_list; + dp->target_list = a; + a->next_usable = dp->usable_list; + dp->usable_list = a; return 1; } Index: sbin/unwind/libunbound/iterator/iter_delegpt.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/iterator/iter_delegpt.h,v diff -u -p -r1.8 iter_delegpt.h --- sbin/unwind/libunbound/iterator/iter_delegpt.h 29 Sep 2025 14:53:38 -0000 1.8 +++ sbin/unwind/libunbound/iterator/iter_delegpt.h 21 Sep 2026 16:28:23 -0000 @@ -221,10 +221,11 @@ int delegpt_add_ns(struct delegpt* dp, s * @param regional: where to allocate the info. * @param ns_rrset: NS rrset. * @param lame: rrset is lame, disprefer it. + * @param port: port or -1 if not set. * @return 0 on alloc error. */ int delegpt_rrset_add_ns(struct delegpt* dp, struct regional* regional, - struct ub_packed_rrset_key* ns_rrset, uint8_t lame); + struct ub_packed_rrset_key* ns_rrset, uint8_t lame, int port); /** * Add target address to the delegation point. @@ -365,11 +366,12 @@ size_t delegpt_count_targets(struct dele * * @param msg: the dns message, referral. * @param regional: where to allocate delegation point. + * @param port: if not -1 specifies a port number. * @return new delegation point or NULL on alloc error, or if the * message was not appropriate. */ struct delegpt* delegpt_from_message(struct dns_msg* msg, - struct regional* regional); + struct regional* regional, int port); /** * Mark negative return in delegation point for specific nameserver. Index: sbin/unwind/libunbound/iterator/iter_donotq.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/iterator/iter_donotq.c,v diff -u -p -r1.1 iter_donotq.c --- sbin/unwind/libunbound/iterator/iter_donotq.c 23 Jan 2019 13:05:27 -0000 1.1 +++ sbin/unwind/libunbound/iterator/iter_donotq.c 21 Sep 2026 16:28:23 -0000 @@ -132,6 +132,18 @@ donotq_apply_cfg(struct iter_donotq* dq, if(cfg->do_ip6) { if(!donotq_str_cfg(dq, "::1")) return 0; + if(!donotq_str_cfg(dq, "::ffff:127.0.0.0/104")) + return 0; + } + /* RFC 1122 3.2.1.3 / RFC 6890 / RFC 4291 2.5.2: not valid as + * destination; on Linux these route to the local host. */ + if(!donotq_str_cfg(dq, "0.0.0.0/8")) + return 0; + if(cfg->do_ip6) { + if(!donotq_str_cfg(dq, "::")) + return 0; + if(!donotq_str_cfg(dq, "::ffff:0:0/96")) + return 0; } } addr_tree_init_parents(&dq->tree); Index: sbin/unwind/libunbound/iterator/iter_fwd.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/iterator/iter_fwd.c,v diff -u -p -r1.7 iter_fwd.c --- sbin/unwind/libunbound/iterator/iter_fwd.c 29 Sep 2025 14:53:38 -0000 1.7 +++ sbin/unwind/libunbound/iterator/iter_fwd.c 21 Sep 2026 16:28:23 -0000 @@ -228,6 +228,11 @@ read_fwds_host(struct config_stub* s, st s->name, p->str); return 0; } + if(dname_subdomain_c(dname, dp->name)) { + log_warn("forward-host '%s' may have a circular " + "dependency on forward-zone '%s'", + p->str, s->name); + } #if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST) if(tls_auth_name) log_err("no name verification functionality in " Index: sbin/unwind/libunbound/iterator/iter_hints.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/iterator/iter_hints.c,v diff -u -p -r1.7 iter_hints.c --- sbin/unwind/libunbound/iterator/iter_hints.c 14 Sep 2025 15:16:53 -0000 1.7 +++ sbin/unwind/libunbound/iterator/iter_hints.c 21 Sep 2026 16:28:23 -0000 @@ -231,6 +231,11 @@ read_stubs_host(struct config_stub* s, s s->name, p->str); return 0; } + if(dname_subdomain_c(dname, dp->name)) { + log_warn("stub-host '%s' may have a circular " + "dependency on stub-zone '%s'", + p->str, s->name); + } #if ! defined(HAVE_SSL_SET1_HOST) && ! defined(HAVE_X509_VERIFY_PARAM_SET1_HOST) if(tls_auth_name) log_err("no name verification functionality in " Index: sbin/unwind/libunbound/iterator/iter_priv.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/iterator/iter_priv.c,v diff -u -p -r1.2 iter_priv.c --- sbin/unwind/libunbound/iterator/iter_priv.c 13 Apr 2024 13:58:34 -0000 1.2 +++ sbin/unwind/libunbound/iterator/iter_priv.c 21 Sep 2026 16:28:23 -0000 @@ -207,6 +207,168 @@ size_t priv_get_mem(struct iter_priv* pr return sizeof(*priv) + regional_get_mem(priv->region); } +/** + * Check if svcparam ipv4hint contains a private address. + * @param priv: private address lookup struct. + * @param d: the data bytes. + * @param data_len: number of data bytes in the svcparam. + * @param addr: address to return the private address to log in to. + * It has space for IPv4 and IPv6 addresses. + * @param addrlen: length of the addr. Returns the correct size for the addr. + * @return true if the rdata contains a private address. + */ +static int svcb_ipv4hint_contains_priv_addr(struct iter_priv* priv, + uint8_t* d, uint16_t data_len, struct sockaddr_storage* addr, + socklen_t* addrlen) +{ + struct sockaddr_in sa; + *addrlen = (socklen_t)sizeof(struct sockaddr_in); + memset(&sa, 0, sizeof(struct sockaddr_in)); + sa.sin_family = AF_INET; + sa.sin_port = (in_port_t)htons(UNBOUND_DNS_PORT); + + while(data_len >= LDNS_IP4ADDRLEN) { + memmove(&sa.sin_addr, d, LDNS_IP4ADDRLEN); + memmove(addr, &sa, *addrlen); + if(priv_lookup_addr(priv, addr, *addrlen)) + return 1; + + d += LDNS_IP4ADDRLEN; + data_len -= LDNS_IP4ADDRLEN; + } + /* if data_len != 0 here, then the svcparam is malformed. */ + return 0; +} + +/** + * Check if svcparam ipv6hint contains a private address. + * @param priv: private address lookup struct. + * @param d: the data bytes. + * @param data_len: number of data bytes in the svcparam. + * @param addr: address to return the private address to log in to. + * It has space for IPv4 and IPv6 addresses. + * @param addrlen: length of the addr. Returns the correct size for the addr. + * @return true if the rdata contains a private address. + */ +static int svcb_ipv6hint_contains_priv_addr(struct iter_priv* priv, + uint8_t* d, uint16_t data_len, struct sockaddr_storage* addr, + socklen_t* addrlen) +{ + struct sockaddr_in6 sa; + *addrlen = (socklen_t)sizeof(struct sockaddr_in6); + memset(&sa, 0, sizeof(struct sockaddr_in6)); + sa.sin6_family = AF_INET6; + sa.sin6_port = (in_port_t)htons(UNBOUND_DNS_PORT); + + while(data_len >= LDNS_IP6ADDRLEN) { + memmove(&sa.sin6_addr, d, LDNS_IP6ADDRLEN); + memmove(addr, &sa, *addrlen); + if(priv_lookup_addr(priv, addr, *addrlen)) + return 1; + + d += LDNS_IP6ADDRLEN; + data_len -= LDNS_IP6ADDRLEN; + } + /* if data_len != 0 here, then the svcparam is malformed. */ + return 0; +} + +/** + * Check if type SVCB and HTTPS rdata contains a private address. + * @param priv: private address lookup struct. + * @param pkt: the packet. + * @param rr: the rr with rdata to check. + * @param addr: address to return the private address to log in to. + * @param addrlen: length of the addr. Initially the total size, on + * return the correct size for the addr. + * @return true if the rdata contains a private address. + */ +static int svcb_rr_contains_priv_addr(struct iter_priv* priv, + sldns_buffer* pkt, struct rr_parse* rr, struct sockaddr_storage* addr, + socklen_t* addrlen) +{ + uint8_t* d = rr->ttl_data; + uint16_t svcparamkey, data_len, rdatalen; + size_t oldpos, dname_len, dname_start, dname_compr_len; + d += 4; /* skip TTL */ + rdatalen = sldns_read_uint16(d); /* read rdata length */ + d += 2; + + if(rdatalen < 2 /* priority */ + 1 /* 1 length target */) + return 0; /* malformed, too short */ + d += 2; /* skip priority */ + rdatalen -= 2; + oldpos = sldns_buffer_position(pkt); + sldns_buffer_set_position(pkt, (size_t)(d - sldns_buffer_begin(pkt))); + dname_start = sldns_buffer_position(pkt); + dname_len = pkt_dname_len(pkt); + dname_compr_len = sldns_buffer_position(pkt) - dname_start; + sldns_buffer_set_position(pkt, oldpos); + if(dname_len == 0) + return 0; /* dname malformed */ + if(dname_compr_len > rdatalen) + return 0; /* malformed */ + d += dname_compr_len; /* skip target */ + rdatalen -= dname_compr_len; + + while(rdatalen >= 4) { + svcparamkey = sldns_read_uint16(d); + data_len = sldns_read_uint16(d+2); + d += 4; + rdatalen -= 4; + + /* verify that we have data_len data */ + if(data_len > rdatalen) { + /* It is malformed, but if there are addresses + * in there it can be rejected. */ + data_len = rdatalen; + } + + if(!data_len) + continue; /* no data for the svcparamkey */ + + if(svcparamkey == SVCB_KEY_IPV4HINT) { + if(svcb_ipv4hint_contains_priv_addr(priv, d, data_len, + addr, addrlen)) + return 1; + } else if(svcparamkey == SVCB_KEY_IPV6HINT) { + if(svcb_ipv6hint_contains_priv_addr(priv, d, data_len, + addr, addrlen)) + return 1; + } + d += data_len; + rdatalen -= data_len; + } + /* If rdatalen != 0 here, then the svcb rdata is malformed. */ + return 0; +} + +/** + * Check if the SVCB and HTTPS rrset is bad. + * @param priv: private address lookup struct. + * @param pkt: the packet. + * @param rrset: the rrset to check. + * @return 1 if the entire rrset has to be removed. 0 if not. + * It removes RRs if they have private addresses, and log that. + */ +static int priv_svcb_rrset_bad(struct iter_priv* priv, sldns_buffer* pkt, + struct rrset_parse* rrset) +{ + struct rr_parse* rr, *prev = NULL; + struct sockaddr_storage addr; + socklen_t addrlen = (socklen_t)sizeof(addr); + for(rr = rrset->rr_first; rr; rr = rr->next) { + if(svcb_rr_contains_priv_addr(priv, pkt, rr, &addr, + &addrlen)) { + if(msgparse_rrset_remove_rr("sanitize: removing public name with private address", pkt, rrset, prev, rr, &addr, addrlen)) + return 1; + continue; + } + prev = rr; + } + return 0; +} + int priv_rrset_bad(struct iter_priv* priv, sldns_buffer* pkt, struct rrset_parse* rrset) { @@ -268,7 +430,11 @@ int priv_rrset_bad(struct iter_priv* pri } prev = rr; } - } + } else if(rrset->type == LDNS_RR_TYPE_SVCB || + rrset->type == LDNS_RR_TYPE_HTTPS) { + if(priv_svcb_rrset_bad(priv, pkt, rrset)) + return 1; + } } return 0; } Index: sbin/unwind/libunbound/iterator/iter_resptype.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/iterator/iter_resptype.c,v diff -u -p -r1.4 iter_resptype.c --- sbin/unwind/libunbound/iterator/iter_resptype.c 13 Apr 2024 13:58:34 -0000 1.4 +++ sbin/unwind/libunbound/iterator/iter_resptype.c 21 Sep 2026 16:28:23 -0000 @@ -107,7 +107,7 @@ response_type_from_cache(struct dns_msg* enum response_type response_type_from_server(int rdset, struct dns_msg* msg, struct query_info* request, struct delegpt* dp, - int* empty_nodata_found) + int* empty_nodata_found, int msg_lame_empty, int msg_lame_referral) { uint8_t* origzone = (uint8_t*)"\000"; /* the default */ struct ub_packed_rrset_key* s; @@ -122,6 +122,10 @@ response_type_from_server(int rdset, /* If the message is NXDOMAIN, then it answers the question. */ if(FLAGS_GET_RCODE(msg->rep->flags) == LDNS_RCODE_NXDOMAIN) { + if(msg->rep->an_numrrsets == 0 && + msg->rep->ns_numrrsets == 0 && + msg_lame_empty) + return RESPONSE_TYPE_LAME; /* make sure its not recursive when we don't want it to */ if( (msg->rep->flags&BIT_RA) && !(msg->rep->flags&BIT_AA) && !rdset) @@ -143,6 +147,10 @@ response_type_from_server(int rdset, if(FLAGS_GET_RCODE(msg->rep->flags) != LDNS_RCODE_NOERROR) return RESPONSE_TYPE_THROWAWAY; + if(msg->rep->an_numrrsets == 0 && msg->rep->ns_numrrsets == 0 && + msg_lame_empty) + return RESPONSE_TYPE_LAME; + /* Note: TC bit has already been handled */ if(dp) { @@ -249,13 +257,16 @@ response_type_from_server(int rdset, * which gives ns==zone delegation from cache * without AA bit as well, with nodata nosoa*/ /* real answer must be +AA and SOA RFC(2308), - * so this is wrong, and we SERVFAIL it if - * this is the only possible reply, if it - * is misdeployed the THROWAWAY makes us pick - * the next server from the selection */ - if(msg->rep->an_numrrsets==0 && + * this is picked up as lame_referral by the + * sanitize step, so it can spot if there + * was data in the answer section before + * removal. If such data is then removed we + * do not want to turn that answer into lame. + * But if it was not there, it can be lame. */ + if(msg_lame_referral && + msg->rep->an_numrrsets==0 && !(msg->rep->flags&BIT_AA) && !rdset) - return RESPONSE_TYPE_THROWAWAY; + return RESPONSE_TYPE_LAME; return RESPONSE_TYPE_ANSWER; } /* If we are getting a referral upwards (or to Index: sbin/unwind/libunbound/iterator/iter_resptype.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/iterator/iter_resptype.h,v diff -u -p -r1.2 iter_resptype.h --- sbin/unwind/libunbound/iterator/iter_resptype.h 13 Apr 2024 13:58:34 -0000 1.2 +++ sbin/unwind/libunbound/iterator/iter_resptype.h 21 Sep 2026 16:28:23 -0000 @@ -120,10 +120,14 @@ enum response_type response_type_from_ca * @param dp: The delegation point that was being queried * when the response was returned. * @param empty_nodata_found: flag to keep track of empty nodata detection. + * @param msg_lame_empty: The scrubber indicates that this empty message + * is lame, before it became empty. + * @param msg_lame_referral: returned true if the reply has a referral before + * scrub. * @return the response type (CNAME or ANSWER). */ enum response_type response_type_from_server(int rdset, struct dns_msg* msg, struct query_info* request, struct delegpt* dp, - int* empty_nodata_found); + int* empty_nodata_found, int msg_lame_empty, int msg_lame_referral); #endif /* ITERATOR_ITER_RESPTYPE_H */ Index: sbin/unwind/libunbound/iterator/iter_scrub.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/iterator/iter_scrub.c,v diff -u -p -r1.8.2.2 iter_scrub.c --- sbin/unwind/libunbound/iterator/iter_scrub.c 28 Nov 2025 18:25:36 -0000 1.8.2.2 +++ sbin/unwind/libunbound/iterator/iter_scrub.c 21 Sep 2026 16:28:23 -0000 @@ -285,6 +285,24 @@ synth_cname_rrset(uint8_t** sname, size_ return NULL; memmove(cn->rr_first->ttl_data, rrset->rr_first->ttl_data, sizeof(uint32_t)); /* RFC6672: synth CNAME TTL == DNAME TTL */ + /* Apply cache TTL policy so DNAME and synthesized CNAME stay equal + * and respect cache-min-ttl/cache-max-ttl (same as rdata_copy path). */ + if(!SERVE_ORIGINAL_TTL) { + uint32_t ttl = sldns_read_uint32(cn->rr_first->ttl_data); + time_t ttl_t = (time_t)ttl; + if(ttl_t < MIN_TTL) ttl_t = MIN_TTL; + if(ttl_t > MAX_TTL) ttl_t = MAX_TTL; + ttl = (uint32_t)ttl_t; + sldns_write_uint32(cn->rr_first->ttl_data, ttl); + /* Do NOT write the clamp back into the packet buffer: + * parse_packet already sized every name from the original + * bytes and rdata_copy re-walks them trusting those sizes; + * mutating packet bytes between the walks breaks that + * invariant (compression pointers can target these TTL + * bytes). The DNAME rrset receives the same clamp at store + * time in rdata_copy, so the DNAME and the synthesized + * CNAME still carry equal TTLs in the cache. */ + } sldns_write_uint16(cn->rr_first->ttl_data+4, aliaslen); memmove(cn->rr_first->ttl_data+6, alias, aliaslen); cn->rr_first->size = sizeof(uint16_t)+aliaslen; @@ -305,6 +323,20 @@ synth_cname_rrset(uint8_t** sname, size_ return cn; } +/** Check if the packet has type NS in answer or authority section */ +static int +pkt_contains_ns(struct msg_parse* msg) +{ + struct rrset_parse* rrset; + for(rrset = msg->rrset_first; rrset; rrset = rrset->rrset_all_next) { + if(rrset->type == LDNS_RR_TYPE_NS && + (rrset->section == LDNS_SECTION_ANSWER || + rrset->section == LDNS_SECTION_AUTHORITY)) + return 1; + } + return 0; +} + /** check if DNAME applies to a name */ static int pkt_strict_sub(sldns_buffer* pkt, uint8_t* sname, uint8_t* dr) @@ -383,6 +415,8 @@ shorten_rrset(sldns_buffer* pkt, struct struct rr_parse* rr = rrset->rr_first, *prev = NULL; if(!rr) return; + if(count < 1) + return; /* cannot leave a still-linked rrset_parse with rr_count == 0 */ for(i=0; inext; @@ -408,6 +442,43 @@ shorten_rrset(sldns_buffer* pkt, struct else rrset->rr_first = NULL; } +/** Shorten RRSIGs list */ +static void +shorten_rrsig(sldns_buffer* pkt, struct rrset_parse* rrset, int count) +{ + /* The too large list of RRSIGs on the RRset is shortened. + * This is so that too large content does not overwhelm the cache. + * The validator does not validate more than a max number of + * RRSIGs as well. */ + int i; + struct rr_parse* rr = rrset->rrsig_first, *prev = NULL; + if(!rr) + return; + for(i=0; inext; + if(!rr) + return; /* The RRSIG list is already short. */ + } + if(verbosity >= VERB_QUERY + && rrset->dname_len <= LDNS_MAX_DOMAINLEN) { + uint8_t buf[LDNS_MAX_DOMAINLEN+1]; + dname_pkt_copy(pkt, buf, rrset->dname); + log_nametypeclass(VERB_QUERY, "normalize: shorten RRSIGs:", + buf, rrset->type, ntohs(rrset->rrset_class)); + } + /* remove further rrsigs */ + rrset->rrsig_last = prev; + rrset->rrsig_count = count; + while(rr) { + rrset->size -= rr->size; + rr = rr->next; + } + if(rrset->rrsig_last) + rrset->rrsig_last->next = NULL; + else rrset->rrsig_first = NULL; +} + /** * This routine normalizes a response. This includes removing "irrelevant" * records from the answer and additional sections and (re)synthesizing @@ -430,6 +501,7 @@ scrub_normalize(sldns_buffer* pkt, struc size_t snamelen = qinfo->qname_len; struct rrset_parse* rrset, *prev, *nsset=NULL; int cname_length = 0; /* number of CNAMEs, or DNAMEs */ + int has_answer = 0; /* if answer section contains nonCNAME,nonDNAME */ if(FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NOERROR && FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NXDOMAIN && @@ -445,6 +517,8 @@ scrub_normalize(sldns_buffer* pkt, struc prev = NULL; rrset = msg->rrset_first; while(rrset && rrset->section == LDNS_SECTION_ANSWER) { + if((int)rrset->rrsig_count > env->cfg->iter_scrub_rrsig) + shorten_rrsig(pkt, rrset, env->cfg->iter_scrub_rrsig); if(cname_length > env->cfg->iter_scrub_cname) { /* Too many CNAMEs, or DNAMEs, from the authority * server, scrub down the length to something @@ -455,8 +529,9 @@ scrub_normalize(sldns_buffer* pkt, struc pkt, msg, prev, &rrset); continue; } - if(rrset->type == LDNS_RR_TYPE_DNAME && - pkt_strict_sub(pkt, sname, rrset->dname)) { + if(rrset->type == LDNS_RR_TYPE_DNAME && + pkt_strict_sub(pkt, sname, rrset->dname) && + pkt_sub(pkt, rrset->dname, zonename)) { /* check if next rrset is correct CNAME. else, * synthesize a CNAME */ struct rrset_parse* nx = rrset->rrset_all_next; @@ -468,6 +543,11 @@ scrub_normalize(sldns_buffer* pkt, struc (unsigned)rrset->rr_count); return 0; } + if(has_answer) { + remove_rrset("normalize: removing DNAME redirection after answer:", + pkt, msg, prev, &rrset); + continue; + } if(!synth_cname(sname, snamelen, rrset, alias, &aliaslen, pkt)) { verbose(VERB_ALGO, "synthesized CNAME " @@ -502,8 +582,6 @@ scrub_normalize(sldns_buffer* pkt, struc log_err("out of memory synthesizing CNAME"); return 0; } - /* FIXME: resolve the conflict between synthesized - * CNAME ttls and the cache. */ rrset = nx; continue; @@ -520,12 +598,18 @@ scrub_normalize(sldns_buffer* pkt, struc if(rrset->type == LDNS_RR_TYPE_CNAME) { struct rrset_parse* nx = rrset->rrset_all_next; uint8_t* oldsname = sname; + if(has_answer) { + remove_rrset("normalize: removing redirection after answer:", + pkt, msg, prev, &rrset); + continue; + } cname_length++; /* see if the next one is a DNAME, if so, swap them */ if(nx && nx->section == LDNS_SECTION_ANSWER && nx->type == LDNS_RR_TYPE_DNAME && nx->rr_count == 1 && - pkt_strict_sub(pkt, sname, nx->dname)) { + pkt_strict_sub(pkt, sname, nx->dname) && + pkt_sub(pkt, nx->dname, zonename)) { /* there is a DNAME after this CNAME, it * is in the ANSWER section, and the DNAME * applies to the name we cover */ @@ -571,6 +655,9 @@ scrub_normalize(sldns_buffer* pkt, struc if(rrset->type == LDNS_RR_TYPE_NS && rrset->rr_count > env->cfg->iter_scrub_ns) { shorten_rrset(pkt, rrset, env->cfg->iter_scrub_ns); + } else if(rrset->type == LDNS_RR_TYPE_DS && + rrset->rr_count > env->cfg->iter_scrub_ns) { + shorten_rrset(pkt, rrset, env->cfg->iter_scrub_ns); } prev = rrset; rrset = rrset->rrset_all_next; @@ -590,6 +677,9 @@ scrub_normalize(sldns_buffer* pkt, struc if(rrset->type == LDNS_RR_TYPE_NS && rrset->rr_count > env->cfg->iter_scrub_ns) { shorten_rrset(pkt, rrset, env->cfg->iter_scrub_ns); + } else if(rrset->type == LDNS_RR_TYPE_DS && + rrset->rr_count > env->cfg->iter_scrub_ns) { + shorten_rrset(pkt, rrset, env->cfg->iter_scrub_ns); } /* Mark the additional names from relevant rrset as OK. */ @@ -597,6 +687,7 @@ scrub_normalize(sldns_buffer* pkt, struc * will be removed by sanitize, so no additional for them */ if(dname_pkt_compare(pkt, qinfo->qname, rrset->dname) == 0) mark_additional_rrset(pkt, msg, rrset); + has_answer = 1; prev = rrset; rrset = rrset->rrset_all_next; @@ -620,6 +711,8 @@ scrub_normalize(sldns_buffer* pkt, struc "RRset:", pkt, msg, prev, &rrset); continue; } + if((int)rrset->rrsig_count > env->cfg->iter_scrub_rrsig) + shorten_rrsig(pkt, rrset, env->cfg->iter_scrub_rrsig); /* only one NS set allowed in authority section */ if(rrset->type==LDNS_RR_TYPE_NS) { /* NS set must be pertinent to the query */ @@ -652,14 +745,14 @@ scrub_normalize(sldns_buffer* pkt, struc * and are removed later. */ if(FLAGS_GET_RCODE(msg->flags) == LDNS_RCODE_NOERROR && msg->an_rrsets != 0 && - 1 /* env->cfg->iter_scrub_promiscuous */) { + env->cfg->iter_scrub_promiscuous) { remove_rrset("normalize: removing promiscuous " "RRset:", pkt, msg, prev, &rrset); continue; } /* Also delete promiscuous NS for other RCODEs */ if(FLAGS_GET_RCODE(msg->flags) != LDNS_RCODE_NOERROR - /* && env->cfg->iter_scrub_promiscuous */) { + && env->cfg->iter_scrub_promiscuous) { remove_rrset("normalize: removing promiscuous " "RRset:", pkt, msg, prev, &rrset); continue; @@ -675,11 +768,16 @@ scrub_normalize(sldns_buffer* pkt, struc && msg->an_rrsets == 0 && !(dname_pkt_compare(pkt, rrset->dname, zonename) != 0 && !soa_in_auth(msg)) - /* && env->cfg->iter_scrub_promiscuous */) { + && env->cfg->iter_scrub_promiscuous) { remove_rrset("normalize: removing promiscuous " "RRset:", pkt, msg, prev, &rrset); continue; } + if(ntohs(rrset->rrset_class) != qinfo->qclass) { + remove_rrset("normalize: removing other class " + "RRset:", pkt, msg, prev, &rrset); + continue; + } if(nsset == NULL) { nsset = rrset; } else { @@ -706,6 +804,11 @@ scrub_normalize(sldns_buffer* pkt, struc shorten_rrset(pkt, rrset, env->cfg->iter_scrub_ns); } } + } else if(rrset->type==LDNS_RR_TYPE_DS) { + if(rrset->rr_count > env->cfg->iter_scrub_ns) { + shorten_rrset(pkt, rrset, + env->cfg->iter_scrub_ns); + } } /* if this is type DS and we query for type DS we just got * a referral answer for our type DS query, fix packet */ @@ -725,7 +828,13 @@ scrub_normalize(sldns_buffer* pkt, struc rrset->rrset_all_next = NULL; return 1; } - mark_additional_rrset(pkt, msg, rrset); + /* Only mark glue as allowed for type NS in the authority + * section. Other RR types do not get glue for them, it + * is allowed from the answer section, but not authority + * so that a message can not have address records cached + * as a side effect to the query. */ + if(rrset->type==LDNS_RR_TYPE_NS) + mark_additional_rrset(pkt, msg, rrset); prev = rrset; rrset = rrset->rrset_all_next; } @@ -762,6 +871,8 @@ scrub_normalize(sldns_buffer* pkt, struc "RRset:", pkt, msg, prev, &rrset); continue; } + if((int)rrset->rrsig_count > env->cfg->iter_scrub_rrsig) + shorten_rrsig(pkt, rrset, env->cfg->iter_scrub_rrsig); prev = rrset; rrset = rrset->rrset_all_next; } @@ -908,12 +1019,20 @@ scrub_sanitize_rr_length(sldns_buffer* p * @param env: module environment with config and cache. * @param ie: iterator environment with private address data. * @param qstate: for setting errinf for EDE error messages. + * @param pkt_before_NS: if the packet had type NS before scrub. If that + * is removed now, that indicates this may have been lame. + * @param msg_lame_empty: returned true if the empty packet is lame. + * @param msg_lame_referral: returned true if the reply has a referral before + * scrub. + * @param rdset: if RD bit was sent in query sent by unbound. * @return 0 on error. */ static int scrub_sanitize(sldns_buffer* pkt, struct msg_parse* msg, struct query_info* qinfo, uint8_t* zonename, struct module_env* env, - struct iter_env* ie, struct module_qstate* qstate) + struct iter_env* ie, struct module_qstate* qstate, + int pkt_before_NS, int* msg_lame_empty, int* msg_lame_referral, + int rdset) { int del_addi = 0; /* if additional-holding rrsets are deleted, we do not trust the normalized additional-A-AAAA any more */ @@ -972,8 +1091,10 @@ scrub_sanitize(sldns_buffer* pkt, struct } /* remove private addresses */ - if( (rrset->type == LDNS_RR_TYPE_A || - rrset->type == LDNS_RR_TYPE_AAAA)) { + if(rrset->type == LDNS_RR_TYPE_A || + rrset->type == LDNS_RR_TYPE_AAAA || + rrset->type == LDNS_RR_TYPE_SVCB || + rrset->type == LDNS_RR_TYPE_HTTPS) { /* do not set servfail since this leads to too * many drops of other people using rfc1918 space */ @@ -1068,6 +1189,21 @@ scrub_sanitize(sldns_buffer* pkt, struct prev = rrset; rrset = rrset->rrset_all_next; } + + /* If the packet is empty now, but it was not before. And there + * was type NS in authority, then that indicates the answer is lame. */ + if(msg->rrset_first == NULL && pkt_before_NS) { + *msg_lame_empty = 1; + verbose(VERB_ALGO, "sanitize: empty message had referral to NS before, marked as lame"); + } else if(pkt_before_NS && msg->an_rrsets==0 && + !(msg->flags&BIT_AA) && !rdset) { + /* If the packet is now a referral, not really a nodata, + * then if it was also with an empty answer section before, + * it is also lame. */ + *msg_lame_referral = 1; + verbose(VERB_ALGO, "sanitize: message has referral not answer, marked as lame"); + } + return 1; } @@ -1075,11 +1211,15 @@ int scrub_message(sldns_buffer* pkt, struct msg_parse* msg, struct query_info* qinfo, uint8_t* zonename, struct regional* region, struct module_env* env, struct module_qstate* qstate, - struct iter_env* ie) + struct iter_env* ie, int* msg_lame_empty, int* msg_lame_referral, + int rdset) { + int pkt_before_NS; /* basic sanity checks */ log_nametypeclass(VERB_ALGO, "scrub for", zonename, LDNS_RR_TYPE_NS, qinfo->qclass); + *msg_lame_empty = 0; + *msg_lame_referral = 0; if(msg->qdcount > 1) return 0; if( !(msg->flags&BIT_QR) ) @@ -1104,11 +1244,21 @@ scrub_message(sldns_buffer* pkt, struct return 0; } + /* If the packet contains type NS in authority before scrub, + * like a self referral. With the answer section empty, it + * was not AA, the query was not sent with RD, with NS in auth, + * and no SOA in auth. For a negative answer, type SOA is present. + * This detects certain lameness if after has removed that. */ + pkt_before_NS = msg->an_rrsets == 0 && + !(msg->flags&BIT_AA) && !rdset && + pkt_contains_ns(msg) && !soa_in_auth(msg); + /* normalize the response, this cleans up the additional. */ if(!scrub_normalize(pkt, msg, qinfo, region, env, zonename)) return 0; /* delete all out-of-zone information */ - if(!scrub_sanitize(pkt, msg, qinfo, zonename, env, ie, qstate)) + if(!scrub_sanitize(pkt, msg, qinfo, zonename, env, ie, qstate, + pkt_before_NS, msg_lame_empty, msg_lame_referral, rdset)) return 0; return 1; } Index: sbin/unwind/libunbound/iterator/iter_scrub.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/iterator/iter_scrub.h,v diff -u -p -r1.2 iter_scrub.h --- sbin/unwind/libunbound/iterator/iter_scrub.h 13 Apr 2024 13:58:34 -0000 1.2 +++ sbin/unwind/libunbound/iterator/iter_scrub.h 21 Sep 2026 16:28:23 -0000 @@ -62,11 +62,16 @@ struct module_qstate; * @param env: module environment with config settings and cache. * @param qstate: for setting errinf for EDE error messages. * @param ie: iterator module environment data. + * @param msg_lame_empty: returned true if the empty packet is lame. + * @param msg_lame_referral: returned true if the reply has a referral before + * scrub. + * @param rdset: if RD bit was sent in query sent by unbound. * @return: false if the message is total waste. true if scrubbed with success. */ int scrub_message(struct sldns_buffer* pkt, struct msg_parse* msg, struct query_info* qinfo, uint8_t* zonename, struct regional* regional, struct module_env* env, struct module_qstate* qstate, - struct iter_env* ie); + struct iter_env* ie, int* msg_lame_empty, int* msg_lame_referral, + int rdset); #endif /* ITERATOR_ITER_SCRUB_H */ Index: sbin/unwind/libunbound/iterator/iter_utils.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/iterator/iter_utils.c,v diff -u -p -r1.15 iter_utils.c --- sbin/unwind/libunbound/iterator/iter_utils.c 14 Sep 2025 15:16:53 -0000 1.15 +++ sbin/unwind/libunbound/iterator/iter_utils.c 21 Sep 2026 16:28:23 -0000 @@ -253,7 +253,9 @@ iter_apply_cfg(struct iter_env* iter_env return 1; } -/** filter out unsuitable targets +/** filter out unsuitable targets. + * Applies NAT64 if needed as well by replacing the IPv4 with the synthesized + * IPv6 address. * @param iter_env: iterator environment with ipv6-support flag. * @param env: module environment with infra cache. * @param name: zone name @@ -306,9 +308,30 @@ iter_filter_unsuitable(struct iter_env* if(a->bogus) return -1; /* address of server is bogus */ if(donotq_lookup(iter_env->donotq, &a->addr, a->addrlen)) { - log_addr(VERB_ALGO, "skip addr on the donotquery list", - &a->addr, a->addrlen); - return -1; /* server is on the donotquery list */ + if(iter_env->nat64.use_nat64 && + addr_is_ip6(&a->addr, a->addrlen) && + a->addrlen == iter_env->nat64.nat64_prefix_addrlen && + addr_in_common(&a->addr, 128, + &iter_env->nat64.nat64_prefix_addr, + iter_env->nat64.nat64_prefix_net, + iter_env->nat64.nat64_prefix_addrlen) == + iter_env->nat64.nat64_prefix_net) { + /* The NAT64 is enabled, and address is IPv6, it is + * in the NAT64 prefix. It is allowed. + * So that in an IPv6-only cluster without internet + * access, that makes the NAT64 translation continue + * to work. The NAT64 prefix is allowed. */ + /* Otherwise, after a timeout, the already NAT64 + * translated address would be treated differently, + * and that causes confusion. */ + log_addr(VERB_ALGO, "the addr is on the donotquery " + "list, but allowed because it is NAT64", + &a->addr, a->addrlen); + } else { + log_addr(VERB_ALGO, "skip addr on the donotquery list", + &a->addr, a->addrlen); + return -1; /* server is on the donotquery list */ + } } if(!iter_env->supports_ipv6 && addr_is_ip6(&a->addr, a->addrlen)) { return -1; /* there is no ip6 available */ @@ -317,6 +340,20 @@ iter_filter_unsuitable(struct iter_env* !addr_is_ip6(&a->addr, a->addrlen)) { return -1; /* there is no ip4 available */ } + if(iter_env->nat64.use_nat64 && !addr_is_ip6(&a->addr, a->addrlen)) { + struct sockaddr_storage real_addr; + socklen_t real_addrlen; + addr_to_nat64(&a->addr, &iter_env->nat64.nat64_prefix_addr, + iter_env->nat64.nat64_prefix_addrlen, + iter_env->nat64.nat64_prefix_net, + &real_addr, &real_addrlen); + log_name_addr(VERB_QUERY, "NAT64 apply: from: ", + name, &a->addr, a->addrlen); + log_name_addr(VERB_QUERY, "NAT64 apply: to: ", + name, &real_addr, real_addrlen); + a->addr = real_addr; + a->addrlen = real_addrlen; + } /* check lameness - need zone , class info */ if(infra_get_lame_rtt(env->infra_cache, &a->addr, a->addrlen, name, namelen, qtype, &lame, &dnsseclame, &reclame, @@ -1276,7 +1313,8 @@ iter_lookup_parent_NS_from_cache(struct log_rrset_key(VERB_ALGO, "found parent-side NS in cache", akey); dp->has_parent_side_NS = 1; /* and mark the new names as lame */ - if(!delegpt_rrset_add_ns(dp, region, akey, 1)) { + if(!delegpt_rrset_add_ns(dp, region, akey, 1, + deleg_port_number(env))) { lock_rw_unlock(&akey->entry.lock); return 0; } @@ -1511,6 +1549,11 @@ iter_stub_fwd_no_cache(struct module_qst struct delegpt *dp; int nolock = 1; + log_assert((retdpname && retdpnamelen + && dpname_storage && dpname_storage_len > 0) || + (retdpname == NULL && retdpnamelen == NULL + && dpname_storage == NULL && dpname_storage_len == 0)); + /* Check for stub. */ /* Lock both forwards and hints for atomic read. */ lock_rw_rdlock(&qstate->env->fwds->lock); @@ -1660,4 +1703,12 @@ iter_make_minimal(struct reply_info* rep rep->ns_numrrsets = 0; rep->ar_numrrsets = 0; rep->rrset_count -= rem; +} + +int +deleg_port_number(struct module_env* env) +{ + if(env->cfg->ssl_upstream) + return env->cfg->ssl_port; + return -1; } Index: sbin/unwind/libunbound/iterator/iter_utils.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/iterator/iter_utils.h,v diff -u -p -r1.11 iter_utils.h --- sbin/unwind/libunbound/iterator/iter_utils.h 14 Sep 2025 15:16:53 -0000 1.11 +++ sbin/unwind/libunbound/iterator/iter_utils.h 21 Sep 2026 16:28:23 -0000 @@ -84,6 +84,7 @@ int iter_apply_cfg(struct iter_env* iter /** * Select a valid, nice target to send query to. * Sorting and removing unsuitable targets is combined. + * Adds records to the infra cache if not already there. * * @param iter_env: iterator module global state, with ip6 enabled and * do-not-query-addresses. @@ -481,5 +482,8 @@ void limit_nsec_ttl(struct dns_msg* msg) * @param rep: reply to modify. */ void iter_make_minimal(struct reply_info* rep); + +/** See if we need a different port number */ +int deleg_port_number(struct module_env* env); #endif /* ITERATOR_ITER_UTILS_H */ Index: sbin/unwind/libunbound/iterator/iterator.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/iterator/iterator.c,v diff -u -p -r1.22 iterator.c --- sbin/unwind/libunbound/iterator/iterator.c 29 Sep 2025 14:53:38 -0000 1.22 +++ sbin/unwind/libunbound/iterator/iterator.c 21 Sep 2026 16:28:24 -0000 @@ -81,7 +81,8 @@ 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); +static void target_count_increase_nx(struct module_qstate* qstate, + struct iter_qstate* iq, int num); int iter_init(struct module_env* env, int id) @@ -250,7 +251,7 @@ error_supers(struct module_qstate* qstat 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); + target_count_increase_nx(super, super_iq, 1); } } if(qstate->qinfo.qtype == LDNS_RR_TYPE_NS) { @@ -297,6 +298,7 @@ error_response_cache(struct module_qstat struct reply_info err; struct msgreply_entry* msg; if(qstate->no_cache_store) { + qstate->error_response_cache = 1; return error_response(qstate, id, rcode); } if(qstate->prefetch_leeway > NORR_TTL) { @@ -733,7 +735,7 @@ is_caps_whitelisted(struct iter_env* ie, * created for the parent query. */ static void -target_count_create(struct iter_qstate* iq) +target_count_create(struct module_qstate* qstate, struct iter_qstate* iq) { if(!iq->target_count) { iq->target_count = (int*)calloc(TARGET_COUNT_MAX, sizeof(int)); @@ -741,33 +743,57 @@ target_count_create(struct iter_qstate* if(iq->target_count) { iq->target_count[TARGET_COUNT_REF] = 1; iq->nxns_dp = (uint8_t**)calloc(1, sizeof(uint8_t*)); + /* continue global quota from where it was. */ + if(qstate->global_quota_reached > + iq->target_count[TARGET_COUNT_GLOBAL_QUOTA]) + iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] = + qstate->global_quota_reached; } } } static void -target_count_increase(struct iter_qstate* iq, int num) +target_count_store(struct module_qstate* qstate, struct iter_qstate* iq) { - target_count_create(iq); + if(iq->target_count) { + /* By storing the global quota counter, it stays + * there to be picked up if the module is restarted, + * eg. due to a validator retry, and then the + * target_count_create routine picks it up. */ + if(iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] > + qstate->global_quota_reached) + qstate->global_quota_reached = + iq->target_count[TARGET_COUNT_GLOBAL_QUOTA]; + } +} + +static void +target_count_increase(struct module_qstate* qstate, + struct iter_qstate* iq, int num) +{ + target_count_create(qstate, iq); if(iq->target_count) iq->target_count[TARGET_COUNT_QUERIES] += num; iq->dp_target_count++; } static void -target_count_increase_nx(struct iter_qstate* iq, int num) +target_count_increase_nx(struct module_qstate* qstate, + struct iter_qstate* iq, int num) { - target_count_create(iq); + target_count_create(qstate, iq); if(iq->target_count) iq->target_count[TARGET_COUNT_NX] += num; } static void -target_count_increase_global_quota(struct iter_qstate* iq, int num) +target_count_increase_global_quota(struct module_qstate* qstate, + struct iter_qstate* iq, int num) { - target_count_create(iq); + target_count_create(qstate, iq); if(iq->target_count) iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] += num; + target_count_store(qstate, iq); } /** @@ -829,7 +855,7 @@ generate_sub_request(uint8_t* qname, siz struct mesh_state* sub = NULL; fptr_ok(fptr_whitelist_modenv_add_sub( qstate->env->add_sub)); - if(!(*qstate->env->add_sub)(qstate, &qinf, + if(!(*qstate->env->add_sub)(qstate, &qinf, NULL, qflags, prime, valrec, &subq, &sub)){ return 0; } @@ -838,8 +864,8 @@ generate_sub_request(uint8_t* qname, siz /* attach subquery, lookup existing or make a new one */ fptr_ok(fptr_whitelist_modenv_attach_sub( qstate->env->attach_sub)); - if(!(*qstate->env->attach_sub)(qstate, &qinf, qflags, prime, - valrec, &subq)) { + if(!(*qstate->env->attach_sub)(qstate, &qinf, NULL, qflags, + prime, valrec, &subq)) { return 0; } } @@ -860,7 +886,7 @@ generate_sub_request(uint8_t* qname, siz subiq = (struct iter_qstate*)subq->minfo[id]; memset(subiq, 0, sizeof(*subiq)); subiq->num_target_queries = 0; - target_count_create(iq); + target_count_create(qstate, iq); subiq->target_count = iq->target_count; if(iq->target_count) { iq->target_count[TARGET_COUNT_REF] ++; /* extra reference */ @@ -1485,6 +1511,7 @@ processInitRequest(struct module_qstate* verbose(VERB_ALGO, "no-cache set, going to the network"); qstate->no_cache_lookup = 1; qstate->no_cache_store = 1; + qstate->fwd_stub_no_cache = 1; msg = NULL; } else if(qstate->blacklist) { /* if cache, or anything else, was blacklisted then @@ -1504,7 +1531,7 @@ processInitRequest(struct module_qstate* msg = val_neg_getmsg(qstate->env->neg_cache, &iq->qchase, qstate->region, qstate->env->rrset_cache, qstate->env->scratch_buffer, - *qstate->env->now, 1/*add SOA*/, NULL, + *qstate->env->now, 1/*add SOA*/, dpname, qstate->env->cfg); } /* item taken from cache does not match our query name, thus @@ -2082,7 +2109,7 @@ query_for_targets(struct module_qstate* ns->resolved = 1; } break; - } + } } /* Send the A request. */ if((ie->supports_ipv4 || ie->nat64.use_nat64) && @@ -2104,7 +2131,7 @@ query_for_targets(struct module_qstate* * a missing target. */ ns->resolved = 1; break; - } + } } /* mark this target as in progress. */ @@ -2229,11 +2256,11 @@ processLastResort(struct module_qstate* errinf(qstate, "could not fetch nameserver"); errinf_dname(qstate, "at zone", iq->dp->name); if(ret == 1) - return error_response(qstate, id, LDNS_RCODE_SERVFAIL); + return error_response(qstate, id, LDNS_RCODE_SERVFAIL); return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL); } iq->num_target_queries += qs; - target_count_increase(iq, qs); + target_count_increase(qstate, iq, qs); if(qs != 0) { qstate->ext_state[id] = module_wait_subquery; return 0; /* and wait for them */ @@ -2289,7 +2316,7 @@ processLastResort(struct module_qstate* * lookups at a time. */ verbose(VERB_ALGO, "try parent-side glue lookup"); iq->num_target_queries += query_count; - target_count_increase(iq, query_count); + target_count_increase(qstate, iq, query_count); qstate->ext_state[id] = module_wait_subquery; return 0; } @@ -2309,7 +2336,7 @@ processLastResort(struct module_qstate* if(query_count != 0) { /* suspend to await results */ verbose(VERB_ALGO, "try parent-side glue lookup"); iq->num_target_queries += query_count; - target_count_increase(iq, query_count); + target_count_increase(qstate, iq, query_count); qstate->ext_state[id] = module_wait_subquery; return 0; } @@ -2365,6 +2392,12 @@ processDSNSFind(struct module_qstate* qs /* go up one (more) step, until we hit the dp, if so, end */ dname_remove_label(&iq->dsns_point, &iq->dsns_point_len); + if(++iq->dsns_count > MAX_DSNS_FIND_COUNT) { + verbose(VERB_QUERY, "DS NS search exceeded %d labels", + MAX_DSNS_FIND_COUNT); + errinf(qstate, "DS NS search exceeded label limit"); + return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL); + } if(query_dname_compare(iq->dsns_point, iq->dp->name) == 0) { /* there was no inbetween nameserver, use the old delegation * point again. And this time, because dsns_point is nonNULL @@ -2436,8 +2469,6 @@ processQueryTargets(struct module_qstate int tf_policy; struct delegpt_addr* target; struct outbound_entry* outq; - struct sockaddr_storage real_addr; - socklen_t real_addrlen; int auth_fallback = 0; uint8_t* qout_orig = NULL; size_t qout_orig_len = 0; @@ -2785,11 +2816,11 @@ processQueryTargets(struct module_qstate if((ret=query_for_targets(qstate, iq, ie, id, -1, &extra))!=0) { errinf(qstate, "could not fetch nameservers for 0x20 fallback"); if(ret == 1) - return error_response(qstate, id, LDNS_RCODE_SERVFAIL); + return error_response(qstate, id, LDNS_RCODE_SERVFAIL); return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL); } iq->num_target_queries += extra; - target_count_increase(iq, extra); + target_count_increase(qstate, iq, extra); if(iq->num_target_queries > 0) { /* wait to get all targets, we want to try em */ verbose(VERB_ALGO, "wait for all targets for fallback"); @@ -2840,7 +2871,7 @@ processQueryTargets(struct module_qstate /* errors ignored, these targets are not strictly necessary for * this result, we do not have to reply with SERVFAIL */ iq->num_target_queries += extra; - target_count_increase(iq, extra); + target_count_increase(qstate, iq, extra); } /* Add the current set of unused targets to our queue. */ @@ -2937,8 +2968,8 @@ processQueryTargets(struct module_qstate errinf(qstate, "could not fetch nameserver"); errinf_dname(qstate, "at zone", iq->dp->name); if(ret == 1) - return error_response(qstate, id, - LDNS_RCODE_SERVFAIL); + return error_response(qstate, id, + LDNS_RCODE_SERVFAIL); return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL); } @@ -2963,7 +2994,7 @@ processQueryTargets(struct module_qstate LDNS_RCODE_SERVFAIL); } iq->num_target_queries += qs; - target_count_increase(iq, qs); + target_count_increase(qstate, iq, qs); } /* Since a target query might have been made, we * need to check again. */ @@ -3023,7 +3054,7 @@ processQueryTargets(struct module_qstate * this result, we do not have to reply with SERVFAIL */ if(extra > 0) { iq->num_target_queries += extra; - target_count_increase(iq, extra); + target_count_increase(qstate, iq, extra); check_waiting_queries(iq, qstate, id); /* undo qname minimise step because we'll get back here * to do it again */ @@ -3036,7 +3067,7 @@ processQueryTargets(struct module_qstate } } - target_count_increase_global_quota(iq, 1); + target_count_increase_global_quota(qstate, iq, 1); if(iq->target_count && iq->target_count[TARGET_COUNT_GLOBAL_QUOTA] > MAX_GLOBAL_QUOTA) { char s[LDNS_MAX_DOMAINLEN]; @@ -3049,7 +3080,9 @@ processQueryTargets(struct module_qstate /* Do not check ratelimit for forwarding queries or if we already got a * pass. */ - sq_check_ratelimit = (!(iq->chase_flags & BIT_RD) && !iq->ratelimit_ok); + sq_check_ratelimit = ((!(iq->chase_flags & BIT_RD) && + !iq->ratelimit_ok)); + iq->ratelimit_incremented = 0; /* We have a valid target. */ if(verbosity >= VERB_QUERY) { log_query_info(VERB_QUERY, "sending query:", &iq->qinfo_out); @@ -3060,17 +3093,6 @@ processQueryTargets(struct module_qstate iq->dnssec_lame_query?" but lame_query anyway": ""); } - real_addr = target->addr; - real_addrlen = target->addrlen; - - 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); - } - fptr_ok(fptr_whitelist_modenv_send_query(qstate->env->send_query)); outq = (*qstate->env->send_query)(&iq->qinfo_out, iq->chase_flags | (iq->chase_to_rd?BIT_RD:0), @@ -3082,11 +3104,12 @@ processQueryTargets(struct module_qstate !qstate->blacklist&&(!iter_qname_indicates_dnssec(qstate->env, &iq->qinfo_out)||target->attempts==1)?0:BIT_CD), iq->dnssec_expected, iq->caps_fallback || is_caps_whitelisted( - ie, iq), sq_check_ratelimit, &real_addr, real_addrlen, + ie, iq), sq_check_ratelimit, &target->addr, target->addrlen, iq->dp->name, iq->dp->namelen, (iq->dp->tcp_upstream || qstate->env->cfg->tcp_upstream), (iq->dp->ssl_upstream || qstate->env->cfg->ssl_upstream), - target->tls_auth_name, qstate, &sq_was_ratelimited); + target->tls_auth_name, qstate, &sq_was_ratelimited, + &iq->ratelimit_incremented); if(!outq) { if(sq_was_ratelimited) { lock_basic_lock(&ie->queries_ratelimit_lock); @@ -3099,7 +3122,7 @@ processQueryTargets(struct module_qstate return error_response_cache(qstate, id, LDNS_RCODE_SERVFAIL); } log_addr(VERB_QUERY, "error sending query to auth server", - &real_addr, real_addrlen); + &target->addr, target->addrlen); if(qstate->env->cfg->qname_minimisation) iq->minimisation_state = SKIP_MINIMISE_STATE; return next_state(iq, QUERYTARGETS_STATE); @@ -3124,7 +3147,6 @@ find_NS(struct reply_info* rep, size_t f return NULL; } - /** * Process the query response. All queries end up at this state first. This * process generally consists of analyzing the response and routing the @@ -3166,7 +3188,8 @@ processQueryResponse(struct module_qstat orig_empty_nodata_found = iq->empty_nodata_found; type = response_type_from_server( (int)((iq->chase_flags&BIT_RD) || iq->chase_to_rd), - iq->response, &iq->qinfo_out, iq->dp, &iq->empty_nodata_found); + iq->response, &iq->qinfo_out, iq->dp, &iq->empty_nodata_found, + iq->msg_lame_empty, iq->msg_lame_referral); iq->chase_to_rd = 0; /* remove TC flag, if this is erroneously set by TCP upstream */ iq->response->rep->flags &= ~BIT_TC; @@ -3236,8 +3259,19 @@ processQueryResponse(struct module_qstat } else iter_scrub_ds(iq->response, NULL, NULL); if(type == RESPONSE_TYPE_THROWAWAY && FLAGS_GET_RCODE(iq->response->rep->flags) == LDNS_RCODE_YXDOMAIN) { - /* YXDOMAIN is a permanent error, no need to retry */ - type = RESPONSE_TYPE_ANSWER; + /* YXDOMAIN is a permanent error for DNAME expansion overflow + * (RFC 6672 Section 2.2). Only accept if the response + * contains a DNAME record in the answer section; otherwise + * treat as invalid, to make sure the authoritative answer + * make sense. */ + size_t i; + for(i=0; iresponse->rep->an_numrrsets; i++) { + if(ntohs(iq->response->rep->rrsets[i]->rk.type) + == LDNS_RR_TYPE_DNAME) { + type = RESPONSE_TYPE_ANSWER; + break; + } + } } if(type == RESPONSE_TYPE_CNAME) origtypecname = 1; @@ -3433,7 +3467,14 @@ processQueryResponse(struct module_qstat iq->deleg_msg = iq->response; /* Keep current delegation point for label comparison */ old_dp = iq->dp; - iq->dp = delegpt_from_message(iq->response, qstate->region); + /* A referral reply is "pleasant", refund the + * parent dp's rate charge before descending to the child. */ + if(iq->ratelimit_incremented) + infra_ratelimit_dec(qstate->env->infra_cache, + old_dp->name, old_dp->namelen, + *qstate->env->now); + iq->dp = delegpt_from_message(iq->response, qstate->region, + deleg_port_number(qstate->env)); if (qstate->env->cfg->qname_minimisation) iq->minimisation_state = INIT_MINIMISE_STATE; if(!iq->dp) { @@ -3616,7 +3657,7 @@ processQueryResponse(struct module_qstat return next_state(iq, INIT_REQUEST_STATE); } else if(type == RESPONSE_TYPE_LAME) { /* Cache the LAMEness. */ - verbose(VERB_DETAIL, "query response was %sLAME", + verbose(VERB_DETAIL, "query response was categorized as %sLAME", dnsseclame?"DNSSEC ":""); if(!dname_subdomain_c(iq->qchase.qname, iq->dp->name)) { log_err("mark lame: mismatch in qname and dpname"); @@ -3655,7 +3696,7 @@ processQueryResponse(struct module_qstat * In this case, the event is just sent directly back to * the QUERYTARGETS_STATE without resetting anything, * because, clearly, the next target must be tried. */ - verbose(VERB_DETAIL, "query response was THROWAWAY"); + verbose(VERB_DETAIL, "query response was categorized as THROWAWAY"); } else { log_warn("A query response came back with an unknown type: %d", (int)type); @@ -3710,7 +3751,8 @@ prime_supers(struct module_qstate* qstat log_assert(qstate->is_priming || foriq->wait_priming_stub); log_assert(qstate->return_rcode == LDNS_RCODE_NOERROR); /* Convert our response to a delegation point */ - dp = delegpt_from_message(qstate->return_msg, forq->region); + dp = delegpt_from_message(qstate->return_msg, forq->region, + deleg_port_number(forq->env)); if(!dp) { /* if there is no convertible delegation point, then * the ANSWER type was (presumably) a negative answer. */ @@ -3761,7 +3803,8 @@ processPrimeResponse(struct module_qstat iq->response->rep->flags &= ~(BIT_RD|BIT_RA); /* ignore rec-lame */ type = response_type_from_server( (int)((iq->chase_flags&BIT_RD) || iq->chase_to_rd), - iq->response, &iq->qchase, iq->dp, NULL); + iq->response, &iq->qchase, iq->dp, NULL, iq->msg_lame_empty, + iq->msg_lame_referral); if(type == RESPONSE_TYPE_ANSWER) { qstate->return_rcode = LDNS_RCODE_NOERROR; qstate->return_msg = iq->response; @@ -3880,7 +3923,7 @@ processTargetResponse(struct module_qsta /* no new addresses, increase the nxns counter, like * this could be a list of wildcards with no new * addresses */ - target_count_increase_nx(foriq, 1); + target_count_increase_nx(qstate, foriq, 1); } verbose(VERB_ALGO, "added target response"); delegpt_log(VERB_ALGO, foriq->dp); @@ -3892,7 +3935,7 @@ processTargetResponse(struct module_qsta dpns->resolved = 1; /* fail the target */ /* do not count cached answers */ if(qstate->reply_origin && qstate->reply_origin->len != 0) { - target_count_increase_nx(foriq, 1); + target_count_increase_nx(qstate, foriq, 1); } } } @@ -3925,7 +3968,8 @@ processDSNSResponse(struct module_qstate /* else, store as DP and continue at querytargets */ foriq->state = QUERYTARGETS_STATE; - foriq->dp = delegpt_from_message(qstate->return_msg, forq->region); + foriq->dp = delegpt_from_message(qstate->return_msg, forq->region, + deleg_port_number(forq->env)); if(!foriq->dp) { log_err("out of memory in dsns dp alloc"); errinf(qstate, "malloc failure, in DS search"); @@ -3974,7 +4018,7 @@ processClassResponse(struct module_qstat /* if there are records, copy RCODE */ /* lower sec_state if this message is lower */ if(from->rep->rrset_count != 0) { - size_t n = from->rep->rrset_count+to->rep->rrset_count; + size_t i, n = from->rep->rrset_count+to->rep->rrset_count; struct ub_packed_rrset_key** dest, **d; /* copy appropriate rcode */ to->rep->flags = from->rep->flags; @@ -3996,24 +4040,49 @@ processClassResponse(struct module_qstat memcpy(dest, to->rep->rrsets, to->rep->an_numrrsets * sizeof(dest[0])); dest += to->rep->an_numrrsets; - memcpy(dest, from->rep->rrsets, from->rep->an_numrrsets - * sizeof(dest[0])); + for(i=0; irep->an_numrrsets; i++) { + dest[i] = packed_rrset_copy_region( + from->rep->rrsets[i], forq->region, 0); + if(!dest[i]) { + log_err("malloc failed in collect ANY"); + foriq->state = FINISHED_STATE; + return; + } + } dest += from->rep->an_numrrsets; /* copy NS */ memcpy(dest, to->rep->rrsets+to->rep->an_numrrsets, to->rep->ns_numrrsets * sizeof(dest[0])); dest += to->rep->ns_numrrsets; - memcpy(dest, from->rep->rrsets+from->rep->an_numrrsets, - from->rep->ns_numrrsets * sizeof(dest[0])); + for(i=0; irep->ns_numrrsets; i++) { + dest[i] = packed_rrset_copy_region( + from->rep->rrsets[ + from->rep->an_numrrsets+i], + forq->region, 0); + if(!dest[i]) { + log_err("malloc failed in collect ANY"); + foriq->state = FINISHED_STATE; + return; + } + } dest += from->rep->ns_numrrsets; /* copy AR */ memcpy(dest, to->rep->rrsets+to->rep->an_numrrsets+ to->rep->ns_numrrsets, to->rep->ar_numrrsets * sizeof(dest[0])); dest += to->rep->ar_numrrsets; - memcpy(dest, from->rep->rrsets+from->rep->an_numrrsets+ - from->rep->ns_numrrsets, - from->rep->ar_numrrsets * sizeof(dest[0])); + for(i=0; irep->ar_numrrsets; i++) { + dest[i] = packed_rrset_copy_region( + from->rep->rrsets[ + from->rep->an_numrrsets+ + from->rep->ns_numrrsets+i], + forq->region, 0); + if(!dest[i]) { + log_err("malloc failed in collect ANY"); + foriq->state = FINISHED_STATE; + return; + } + } /* update counts */ to->rep->rrsets = d; to->rep->an_numrrsets += from->rep->an_numrrsets; @@ -4117,6 +4186,7 @@ processFinished(struct module_qstate* qs iter_store_parentside_neg(qstate->env, &qstate->qinfo, iq->deleg_msg?iq->deleg_msg->rep: (iq->response?iq->response->rep:NULL)); + target_count_store(qstate, iq); if(!iq->response) { verbose(VERB_ALGO, "No response is set, servfail"); errinf(qstate, "(no response found at query finish)"); @@ -4370,7 +4440,10 @@ process_response(struct module_qstate* q /* normalize and sanitize: easy to delete items from linked lists */ if(!scrub_message(pkt, prs, &iq->qinfo_out, iq->dp->name, - qstate->env->scratch, qstate->env, qstate, ie)) { + qstate->env->scratch, qstate->env, qstate, ie, + &iq->msg_lame_empty, &iq->msg_lame_referral, + (int)((iq->chase_flags&BIT_RD) || iq->chase_to_rd) + )) { /* if 0x20 enabled, start fallback, but we have no message */ if(event == module_event_capsfail && !iq->caps_fallback) { iq->caps_fallback = 1; @@ -4532,6 +4605,7 @@ iter_clear(struct module_qstate* qstate, iq = (struct iter_qstate*)qstate->minfo[id]; if(iq) { outbound_list_clear(&iq->outlist); + target_count_store(qstate, iq); if(iq->target_count && --iq->target_count[TARGET_COUNT_REF] == 0) { free(iq->target_count); if(*iq->nxns_dp) free(*iq->nxns_dp); Index: sbin/unwind/libunbound/iterator/iterator.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/iterator/iterator.h,v diff -u -p -r1.12 iterator.h --- sbin/unwind/libunbound/iterator/iterator.h 14 Sep 2025 15:16:53 -0000 1.12 +++ sbin/unwind/libunbound/iterator/iterator.h 21 Sep 2026 16:28:24 -0000 @@ -104,6 +104,11 @@ extern int BLACKLIST_PENALTY; #define RTT_BAND 400 /** Number of retries for empty nodata packets before it is accepted. */ #define EMPTY_NODATA_RETRY_COUNT 2 +/** max label-strip iterations in DSNS_FIND_STATE (RFC 4035 4.2 parent-NS + * search) before giving up; bounds upstream NS sends per client DS. + * Means the max number of labels in grandchild to the grandparent zone that + * are co-hosted. */ +#define MAX_DSNS_FIND_COUNT 20 /** * Iterator global state for nat64. @@ -375,6 +380,10 @@ struct iter_qstate { /** if true, already tested for ratelimiting and passed the test */ int ratelimit_ok; + /** If the last query, that may be a referral, incremented the + * ratelimit counter. */ + int ratelimit_incremented; + /** * The query must store NS records from referrals as parentside RRs * Enabled once it hits resolution problems, to throttle retries. @@ -399,6 +408,8 @@ struct iter_qstate { uint8_t* dsns_point; /** length of the dname in dsns_point */ size_t dsns_point_len; + /** number of label-strip iterations performed in DSNS_FIND_STATE */ + int dsns_count; /** * expected dnssec information for this iteration step. @@ -433,6 +444,13 @@ struct iter_qstate { * This flag detects that a completely empty nodata was received, * already so that it is accepted later. */ int empty_nodata_found; + + /** Store if the answer was empty, but lame, before it became empty.*/ + int msg_lame_empty; + + /** Store if the answer was a referral, to self, before scrub. So the + * it is not some sort of answer. */ + int msg_lame_referral; /** list of pending queries to authoritative servers. */ struct outbound_list outlist; Index: sbin/unwind/libunbound/libunbound/context.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/libunbound/context.h,v diff -u -p -r1.5 context.h --- sbin/unwind/libunbound/libunbound/context.h 5 Sep 2023 15:44:01 -0000 1.5 +++ sbin/unwind/libunbound/libunbound/context.h 21 Sep 2026 16:28:24 -0000 @@ -167,6 +167,8 @@ struct ctx_query { ub_event_callback_type cb_event; /** for async query, the callback user arg */ void* cb_arg; + /** for async query the unique info */ + void* unique_info; /** answer message, result from resolver lookup. */ uint8_t* msg; Index: sbin/unwind/libunbound/libunbound/libunbound.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/libunbound/libunbound.c,v diff -u -p -r1.12 libunbound.c --- sbin/unwind/libunbound/libunbound/libunbound.c 5 Sep 2024 08:22:47 -0000 1.12 +++ sbin/unwind/libunbound/libunbound/libunbound.c 21 Sep 2026 16:28:24 -0000 @@ -571,6 +571,8 @@ ub_ctx_async(struct ub_ctx* ctx, int dot int ub_poll(struct ub_ctx* ctx) { + if(!ctx || ctx->event_base) + return UB_INITFAIL; /* no need to hold lock while testing for readability. */ return tube_poll(ctx->rr_pipe); } @@ -578,6 +580,8 @@ ub_poll(struct ub_ctx* ctx) int ub_fd(struct ub_ctx* ctx) { + if(!ctx || ctx->event_base) + return -1; return tube_read_fd(ctx->rr_pipe); } @@ -672,6 +676,8 @@ ub_process(struct ub_ctx* ctx) int r; uint8_t* msg; uint32_t len; + if(!ctx || ctx->event_base) + return UB_INITFAIL; while(1) { msg = NULL; lock_basic_lock(&ctx->rrpipe_lock); @@ -700,6 +706,8 @@ ub_wait(struct ub_ctx* ctx) int r; uint8_t* msg; uint32_t len; + if(!ctx || ctx->event_base) + return UB_INITFAIL; /* this is basically the same loop as _process(), but with changes. * holds the rrpipe lock and waits with tube_wait */ while(1) { @@ -837,6 +845,8 @@ ub_resolve_async(struct ub_ctx* ctx, con struct ctx_query* q; uint8_t* msg = NULL; uint32_t len = 0; + if(!ctx || ctx->event_base) + return UB_INITFAIL; if(async_id) *async_id = 0; @@ -1467,8 +1477,15 @@ ub_ctx_set_event(struct ub_ctx* ctx, str lock_basic_lock(&ctx->cfglock); /* destroy the current worker - safe to pass in NULL */ + + /* Unlock the cfglock during libworker_delete_event, since it + * calls context_release_alloc, that wants to lock cfglock again. + * Since the event base is used from one thread, the one that + * called this function, it is safe to do so. */ + lock_basic_unlock(&ctx->cfglock); libworker_delete_event(ctx->event_worker); ctx->event_worker = NULL; + lock_basic_lock(&ctx->cfglock); new_base = ub_libevent_event_base(base); if (new_base) ctx->event_base = new_base; Index: sbin/unwind/libunbound/libunbound/libworker.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/libunbound/libworker.c,v diff -u -p -r1.18 libworker.c --- sbin/unwind/libunbound/libunbound/libworker.c 29 Sep 2025 14:53:38 -0000 1.18 +++ sbin/unwind/libunbound/libunbound/libworker.c 21 Sep 2026 16:28:24 -0000 @@ -105,6 +105,7 @@ libworker_delete_env(struct libworker* w SSL_CTX_free(w->sslctx); #endif outside_network_delete(w->back); + shared_ports_delete(w->shared_ports); } /** delete libworker struct */ @@ -219,17 +220,25 @@ libworker_setup(struct ub_ctx* ctx, int libworker_delete(w); return NULL; } + if(!(w->shared_ports = shared_ports_create(cfg->out_ifs, + cfg->num_out_ifs, cfg->do_ip4, cfg->do_ip6, ports, numports))) { + if(!w->is_bg || w->is_bg_thread) { + lock_basic_unlock(&ctx->cfglock); + } + libworker_delete(w); + return NULL; + } w->back = outside_network_create(w->base, cfg->msg_buffer_size, (size_t)cfg->outgoing_num_ports, cfg->out_ifs, cfg->num_out_ifs, cfg->do_ip4, cfg->do_ip6, cfg->do_tcp?cfg->outgoing_num_tcp:0, cfg->ip_dscp, w->env->infra_cache, w->env->rnd, cfg->use_caps_bits_for_id, - ports, numports, cfg->unwanted_threshold, + cfg->unwanted_threshold, cfg->outgoing_tcp_mss, &libworker_alloc_cleanup, w, cfg->do_udp || cfg->udp_upstream_without_downstream, w->sslctx, cfg->delay_close, cfg->tls_use_sni, NULL, cfg->udp_connect, cfg->max_reuse_tcp_queries, cfg->tcp_reuse_timeout, - cfg->tcp_auth_query_timeout); + cfg->tcp_auth_query_timeout, w->shared_ports); w->env->outnet = w->back; if(!w->is_bg || w->is_bg_thread) { lock_basic_unlock(&ctx->cfglock); @@ -642,7 +651,8 @@ int libworker_fg(struct ub_ctx* ctx, str } /* process new query */ if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns, - w->back->udp_buff, qid, libworker_fg_done_cb, q, 0)) { + w->back->udp_buff, qid, libworker_fg_done_cb, q, 0, + &q->unique_info)) { free(qinfo.qname); return UB_NOMEM; } @@ -723,7 +733,8 @@ int libworker_attach_mesh(struct ub_ctx* if(async_id) *async_id = q->querynum; if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns, - w->back->udp_buff, qid, libworker_event_done_cb, q, 0)) { + w->back->udp_buff, qid, libworker_event_done_cb, q, 0, + &q->unique_info)) { free(qinfo.qname); return UB_NOMEM; } @@ -861,7 +872,8 @@ handle_newq(struct libworker* w, uint8_t q->w = w; /* process new query */ if(!mesh_new_callback(w->env->mesh, &qinfo, qflags, &edns, - w->back->udp_buff, qid, libworker_bg_done_cb, q, 0)) { + w->back->udp_buff, qid, libworker_bg_done_cb, q, 0, + &q->unique_info)) { add_bg_result(w, q, NULL, UB_NOMEM, NULL, 0); } free(qinfo.qname); @@ -879,7 +891,8 @@ struct outbound_entry* libworker_send_qu int check_ratelimit, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name, - struct module_qstate* q, int* was_ratelimited) + struct module_qstate* q, int* was_ratelimited, + int* ratelimit_incremented) { struct libworker* w = (struct libworker*)q->env->worker; struct outbound_entry* e = (struct outbound_entry*)regional_alloc( @@ -891,7 +904,7 @@ struct outbound_entry* libworker_send_qu want_dnssec, nocaps, check_ratelimit, tcp_upstream, ssl_upstream, tls_auth_name, addr, addrlen, zone, zonelen, q, libworker_handle_service_reply, e, w->back->udp_buff, q->env, - was_ratelimited); + was_ratelimited, ratelimit_incremented); if(!e->qsent) { return NULL; } @@ -976,7 +989,8 @@ struct outbound_entry* worker_send_query struct sockaddr_storage* ATTR_UNUSED(addr), socklen_t ATTR_UNUSED(addrlen), uint8_t* ATTR_UNUSED(zone), size_t ATTR_UNUSED(zonelen), int ATTR_UNUSED(tcp_upstream), int ATTR_UNUSED(ssl_upstream), char* ATTR_UNUSED(tls_auth_name), - struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited)) + struct module_qstate* ATTR_UNUSED(q), int* ATTR_UNUSED(was_ratelimited), + int* ATTR_UNUSED(ratelimit_incremented)) { log_assert(0); return 0; Index: sbin/unwind/libunbound/libunbound/libworker.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/libunbound/libworker.h,v diff -u -p -r1.1 libworker.h --- sbin/unwind/libunbound/libunbound/libworker.h 23 Jan 2019 13:05:27 -0000 1.1 +++ sbin/unwind/libunbound/libunbound/libworker.h 21 Sep 2026 16:28:24 -0000 @@ -60,6 +60,7 @@ struct tube; struct sldns_buffer; struct ub_event_base; struct query_info; +struct shared_ports; /** * The library-worker status structure @@ -84,6 +85,8 @@ struct libworker { struct comm_base* base; /** the backside outside network interface to the auth servers */ struct outside_network* back; + /** shared ports structure */ + struct shared_ports* shared_ports; /** random() table for this worker. */ struct ub_randstate* rndstate; /** sslcontext for SSL wrapped DNS over TCP queries */ Index: sbin/unwind/libunbound/libunbound/unbound.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/libunbound/unbound.h,v diff -u -p -r1.12 unbound.h --- sbin/unwind/libunbound/libunbound/unbound.h 29 Sep 2025 14:53:38 -0000 1.12 +++ sbin/unwind/libunbound/libunbound/unbound.h 21 Sep 2026 16:28:24 -0000 @@ -853,6 +853,8 @@ struct ub_server_stats { long long qquic; /** number of queries removed due to discard-timeout */ long long num_queries_discard_timeout; + /** number of queries removed due to replyaddr limit */ + long long num_queries_replyaddr_limit; /** number of queries removed due to wait-limit */ long long num_queries_wait_limit; /** number of dns error reports generated */ @@ -872,6 +874,8 @@ struct ub_stats_info { long long mesh_num_states; /** mesh stats: current number of reply (user) states */ long long mesh_num_reply_states; + /** mesh stats: current number of reply entries */ + long long mesh_num_reply_addrs; /** mesh stats: number of reply states overwritten with a new one */ long long mesh_jostled; /** mesh stats: number of incoming queries dropped */ Index: sbin/unwind/libunbound/libunbound/worker.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/libunbound/worker.h,v diff -u -p -r1.3 worker.h --- sbin/unwind/libunbound/libunbound/worker.h 1 Mar 2022 18:34:22 -0000 1.3 +++ sbin/unwind/libunbound/libunbound/worker.h 21 Sep 2026 16:28:24 -0000 @@ -70,6 +70,8 @@ struct query_info; * @param q: which query state to reactivate upon return. * @param was_ratelimited: it will signal back if the query failed to pass the * ratelimit check. + * @param ratelimit_incremented: set to true if the ratelimit counter + * was increased. * @return: false on failure (memory or socket related). no query was * sent. */ @@ -78,7 +80,8 @@ struct outbound_entry* libworker_send_qu int check_ratelimit, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name, - struct module_qstate* q, int* was_ratelimited); + struct module_qstate* q, int* was_ratelimited, + int* ratelimit_incremented); /** process incoming serviced query replies from the network */ int libworker_handle_service_reply(struct comm_point* c, void* arg, int error, @@ -126,6 +129,8 @@ void worker_sighandler(int sig, void* ar * @param q: which query state to reactivate upon return. * @param was_ratelimited: it will signal back if the query failed to pass the * ratelimit check. + * @param ratelimit_incremented: set to true if the ratelimit counter + * was increased. * @return: false on failure (memory or socket related). no query was * sent. */ @@ -134,7 +139,8 @@ struct outbound_entry* worker_send_query int check_ratelimit, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name, - struct module_qstate* q, int* was_ratelimited); + struct module_qstate* q, int* was_ratelimited, + int* ratelimit_incremented); /** * process control messages from the main thread. Frees the control @@ -170,14 +176,5 @@ void worker_start_accept(void* arg); /** stop accept callback handler */ void worker_stop_accept(void* arg); - -/** handle remote control accept callbacks */ -int remote_accept_callback(struct comm_point*, void*, int, struct comm_reply*); - -/** handle remote control data callbacks */ -int remote_control_callback(struct comm_point*, void*, int, struct comm_reply*); - -/** routine to printout option values over SSL */ -void remote_get_opt_ssl(char* line, void* arg); #endif /* LIBUNBOUND_WORKER_H */ Index: sbin/unwind/libunbound/respip/respip.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/respip/respip.c,v diff -u -p -r1.15 respip.c --- sbin/unwind/libunbound/respip/respip.c 14 Sep 2025 15:16:53 -0000 1.15 +++ sbin/unwind/libunbound/respip/respip.c 21 Sep 2026 16:28:24 -0000 @@ -899,27 +899,34 @@ respip_rewrite_reply(const struct query_ int rpz_cname_override = 0; char* log_name = NULL; - if(!cinfo) - goto done; - ctaglist = cinfo->taglist; - ctaglen = cinfo->taglen; - tag_actions = cinfo->tag_actions; - tag_actions_size = cinfo->tag_actions_size; - tag_datas = cinfo->tag_datas; - tag_datas_size = cinfo->tag_datas_size; - 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; + if(!cinfo) { + /* Internal mesh sub-query (e.g. dns64 A lookup): no + * per-client view/tags, but global response-ip and RPZ + * rpz-ip must still apply. */ + ctaglist = NULL; ctaglen = 0; + tag_actions = NULL; tag_actions_size = 0; + tag_datas = NULL; tag_datas_size = 0; + } else { + ctaglist = cinfo->taglist; + ctaglen = cinfo->taglen; + tag_actions = cinfo->tag_actions; + tag_actions_size = cinfo->tag_actions_size; + tag_datas = cinfo->tag_datas; + tag_datas_size = cinfo->tag_datas_size; + 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. */ } - /* The view is rdlocked by views_find_view. */ } log_assert(ipset); @@ -973,6 +980,9 @@ respip_rewrite_reply(const struct query_ lock_rw_unlock(&raddr->lock); lock_rw_unlock(&a->lock); lock_rw_unlock(&az->rpz_lock); + if(view) { + lock_rw_unlock(&view->lock); + } return 0; } if(rpz_used) { @@ -1074,7 +1084,8 @@ generate_cname_request(struct module_qst subqi.qtype = qstate->qinfo.qtype; subqi.qclass = qstate->qinfo.qclass; fptr_ok(fptr_whitelist_modenv_attach_sub(qstate->env->attach_sub)); - return (*qstate->env->attach_sub)(qstate, &subqi, BIT_RD, 0, 0, &subq); + return (*qstate->env->attach_sub)(qstate, &subqi, + qstate->client_info, BIT_RD, 0, 0, &subq); } void @@ -1110,7 +1121,13 @@ respip_operate(struct module_qstate* qst if((qstate->qinfo.qtype == LDNS_RR_TYPE_A || qstate->qinfo.qtype == LDNS_RR_TYPE_AAAA || qstate->qinfo.qtype == LDNS_RR_TYPE_ANY) && - qstate->return_msg && qstate->return_msg->rep) { + qstate->return_msg && qstate->return_msg->rep && + !(qstate->env->need_to_validate && + (!(qstate->query_flags & BIT_CD) + || qstate->env->cfg->ignore_cd) && + (qstate->return_msg->rep->security <= sec_status_bogus + || qstate->return_msg->rep->security == + sec_status_secure_sentinel_fail))) { struct reply_info* new_rep = qstate->return_msg->rep; struct ub_packed_rrset_key* alias_rrset = NULL; struct respip_action_info actinfo = {0, 0, 0, 0, NULL, 0, NULL}; @@ -1147,8 +1164,10 @@ respip_operate(struct module_qstate* qst * clients. */ qstate->is_drop = 1; } else if(alias_rrset) { - if(!generate_cname_request(qstate, alias_rrset)) + if(!generate_cname_request(qstate, alias_rrset)) { + errinf(qstate, "Could not generate CNAME request"); goto servfail; + } next_state = module_wait_subquery; } qstate->return_msg->rep = new_rep; @@ -1162,6 +1181,7 @@ respip_operate(struct module_qstate* qst servfail: qstate->return_rcode = LDNS_RCODE_SERVFAIL; qstate->return_msg = NULL; + qstate->ext_state[id] = module_finished; } int @@ -1233,7 +1253,8 @@ respip_inform_super(struct module_qstate struct respip_qstate* rq = (struct respip_qstate*)super->minfo[id]; struct reply_info* new_rep = NULL; - rq->state = RESPIP_SUBQUERY_FINISHED; + if(rq) + rq->state = RESPIP_SUBQUERY_FINISHED; /* respip subquery should have always been created with a valid reply * in super. */ @@ -1257,6 +1278,7 @@ respip_inform_super(struct module_qstate return; fail: + errinf(super, "CNAME lookup failed"); super->return_rcode = LDNS_RCODE_SERVFAIL; super->return_msg = NULL; return; Index: sbin/unwind/libunbound/services/authzone.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/services/authzone.c,v diff -u -p -r1.23 authzone.c --- sbin/unwind/libunbound/services/authzone.c 29 Sep 2025 14:53:38 -0000 1.23 +++ sbin/unwind/libunbound/services/authzone.c 21 Sep 2026 16:28:24 -0000 @@ -55,6 +55,7 @@ #include "util/log.h" #include "util/module.h" #include "util/random.h" +#include "util/timeval_func.h" #include "services/cache/dns.h" #include "services/outside_network.h" #include "services/listen_dnsport.h" @@ -95,6 +96,8 @@ /** number of timeouts before we fallback from IXFR to AXFR, * because some versions of servers (eg. dnsmasq) drop IXFR packets. */ #define NUM_TIMEOUTS_FALLBACK_IXFR 3 +/** number of IXFRs before an AXFR is performed, to consolidate RPZ memory. */ +#define NUM_IXFR_BEFORE_AXFR 5 /** pick up nextprobe task to start waiting to perform transfer actions */ static void xfr_set_timeout(struct auth_xfer* xfr, struct module_env* env, @@ -106,6 +109,9 @@ static void xfr_probe_send_or_end(struct * or transfer task if nothing to probe, or false if already in progress */ static int xfr_start_probe(struct auth_xfer* xfr, struct module_env* env, struct auth_master* spec); +/** copy the master addresses from the task_probe lookups to the allow_notify + * list of masters */ +static void probe_copy_masters_for_allow_notify(struct auth_xfer* xfr); /** delete xfer structure (not its tree entry) */ void auth_xfer_delete(struct auth_xfer* xfr); @@ -171,7 +177,7 @@ get_rrset_ttl(struct ub_packed_rrset_key /** Copy rrset into region from domain-datanode and packet rrset */ static struct ub_packed_rrset_key* auth_packed_rrset_copy_region(struct auth_zone* z, struct auth_data* node, - struct auth_rrset* rrset, struct regional* region, time_t adjust) + struct auth_rrset* rrset, struct regional* region) { struct ub_packed_rrset_key key; memset(&key, 0, sizeof(key)); @@ -182,7 +188,7 @@ auth_packed_rrset_copy_region(struct aut key.rk.type = htons(rrset->type); key.rk.rrset_class = htons(z->dclass); key.entry.hash = rrset_key_hash(&key.rk); - return packed_rrset_copy_region(&key, region, adjust); + return packed_rrset_copy_region(&key, region, 0); } /** fix up msg->rep TTL and prefetch ttl */ @@ -236,7 +242,7 @@ msg_add_rrset_an(struct auth_zone* z, st return 0; /* copy it */ if(!(msg->rep->rrsets[msg->rep->rrset_count] = - auth_packed_rrset_copy_region(z, node, rrset, region, 0))) + auth_packed_rrset_copy_region(z, node, rrset, region))) return 0; msg->rep->rrset_count++; msg->rep->an_numrrsets++; @@ -260,7 +266,7 @@ msg_add_rrset_ns(struct auth_zone* z, st return 0; /* copy it */ if(!(msg->rep->rrsets[msg->rep->rrset_count] = - auth_packed_rrset_copy_region(z, node, rrset, region, 0))) + auth_packed_rrset_copy_region(z, node, rrset, region))) return 0; msg->rep->rrset_count++; msg->rep->ns_numrrsets++; @@ -283,7 +289,7 @@ msg_add_rrset_ar(struct auth_zone* z, st return 0; /* copy it */ if(!(msg->rep->rrsets[msg->rep->rrset_count] = - auth_packed_rrset_copy_region(z, node, rrset, region, 0))) + auth_packed_rrset_copy_region(z, node, rrset, region))) return 0; msg->rep->rrset_count++; msg->rep->ar_numrrsets++; @@ -386,6 +392,20 @@ auth_data_del(rbnode_type* n, void* ATTR auth_data_delete(z); } +/** delete chunklist */ +static void +auth_chunk_list_delete(struct auth_chunk* first) +{ + struct auth_chunk* c, *cn; + c = first; + while(c) { + cn = c->next; + free(c->data); + free(c); + c = cn; + } +} + /** delete an auth zone structure (tree remove must be done elsewhere) */ static void auth_zone_delete(struct auth_zone* z, struct auth_zones* az) @@ -407,6 +427,7 @@ auth_zone_delete(struct auth_zone* z, st } if(z->rpz) rpz_delete(z->rpz); + auth_chunk_list_delete(z->perform_write_chunk_list); free(z->name); free(z->zonefile); free(z); @@ -432,7 +453,12 @@ auth_zone_create(struct auth_zones* az, rbtree_init(&z->data, &auth_data_cmp); lock_rw_init(&z->lock); lock_protect(&z->lock, &z->name, sizeof(*z)-sizeof(rbnode_type)- - sizeof(&z->rpz_az_next)-sizeof(&z->rpz_az_prev)); + sizeof(z->rpz_az_next)-sizeof(z->rpz_az_prev)- + sizeof(z->max_transfer_size)-sizeof(z->max_transfer_size)); + lock_protect(&z->lock, &z->max_transfer_size, + sizeof(z->max_transfer_size)); + lock_protect(&z->lock, &z->max_transfer_time, + sizeof(z->max_transfer_time)); lock_rw_wrlock(&z->lock); /* z lock protects all, except rbtree itself and the rpz linked list * pointers, which are protected using az->lock */ @@ -1175,6 +1201,22 @@ az_insert_rr(struct auth_zone* z, uint8_ log_err("wrong class for RR"); return 0; } + if(rr_type == LDNS_RR_TYPE_A && rdatalen != 6 /* 2 + 4 */) { + log_err("malformed A record"); + return 0; + } else if(rr_type == LDNS_RR_TYPE_AAAA && rdatalen != 18 /* 2 + 16 */) { + log_err("malformed AAAA record"); + return 0; + } + if(!dname_subdomain_c(dname, z->name)) { + char nm[LDNS_MAX_DOMAINLEN], zn[LDNS_MAX_DOMAINLEN]; + dname_str(dname, nm); + dname_str(z->name, zn); + verbose(VERB_ALGO, "auth-zone %s: dropping out-of-zone RR " + "%s", zn, nm); + if(duplicate) *duplicate=1; /* treat as bad insert */ + return 1; + } if(!(node=az_domain_find_or_create(z, dname, dname_len))) { log_err("cannot create domain"); return 0; @@ -1182,6 +1224,10 @@ az_insert_rr(struct auth_zone* z, uint8_ if(!az_domain_add_rr(node, rr_type, rr_ttl, rdata, rdatalen, duplicate)) { log_err("cannot add RR to domain"); + if(node->rrsets == NULL) { + (void)rbtree_delete(&z->data, node); + auth_data_delete(node); + } return 0; } if(z->rpz) { @@ -1369,6 +1415,10 @@ decompress_rr_into_buffer(struct sldns_b uncompressed_len = pkt_dname_len(&pktbuf); if(!uncompressed_len) return 0; /* parse error in dname */ + compressed_len = sldns_buffer_position( + &pktbuf) - oldpos; + if(compressed_len > rdlen) + return 0; /* dname exceeds rdata */ if(!sldns_buffer_available(buf, uncompressed_len)) /* dname too long for buffer */ @@ -1376,14 +1426,15 @@ decompress_rr_into_buffer(struct sldns_b dname_pkt_copy(&pktbuf, sldns_buffer_current(buf), rd); sldns_buffer_skip(buf, (ssize_t)uncompressed_len); - compressed_len = sldns_buffer_position( - &pktbuf) - oldpos; rd += compressed_len; rdlen -= compressed_len; count--; len = 0; break; case LDNS_RDF_TYPE_STR: + /* Check rdlen for resilience, because it is + * checked above, that rdlen > 0 */ + if(rdlen < 1) return 0; /* malformed */ len = rd[0] + 1; break; default: @@ -1391,6 +1442,8 @@ decompress_rr_into_buffer(struct sldns_b break; } if(len) { + if(len > rdlen) + return 0; /* malformed */ if(!sldns_buffer_available(buf, len)) return 0; /* too long for buffer */ sldns_buffer_write(buf, rd, len); @@ -1498,6 +1551,11 @@ az_parse_file(struct auth_zone* z, FILE* "exceeded", fname, state->lineno); return 0; } + /* A $INCLUDE is not expected for a secondary zone. */ + if(z->zone_is_slave) { + log_err("%s:%d $INCLUDE not allowed for secondary zone", fname, state->lineno); + return 0; + } /* skip spaces */ while(*incfile == ' ' || *incfile == '\t') incfile++; @@ -1563,6 +1621,16 @@ az_parse_file(struct auth_zone* z, FILE* return 1; } +void auth_zone_clear_data(struct auth_zone* z) +{ + /* clear the data tree */ + traverse_postorder(&z->data, auth_data_del, NULL); + rbtree_init(&z->data, &auth_data_cmp); + /* clear the RPZ policies */ + if(z->rpz) + rpz_clear(z->rpz); +} + int auth_zone_read_zonefile(struct auth_zone* z, struct config_file* cfg) { @@ -1585,10 +1653,16 @@ auth_zone_read_zonefile(struct auth_zone in = fopen(zfilename, "r"); if(!in) { char* n = sldns_wire2str_dname(z->name, z->namelen); - if(z->zone_is_slave && errno == ENOENT) { - /* we fetch the zone contents later, no file yet */ - verbose(VERB_ALGO, "no zonefile %s for %s", - zfilename, n?n:"error"); + if(errno == ENOENT) { + /* For a secondary, fetch the zone contents later, no + * file yet. For a primary, no way to fetch the zone, + * so warn. */ + if(z->zone_is_slave) + verbose(VERB_ALGO, "no zonefile %s for %s", + zfilename, n?n:"error"); + else + log_warn("no zonefile %s for %s", + zfilename, n?n:"error"); free(n); return 1; } @@ -1791,9 +1865,11 @@ auth_zones_read_zones(struct auth_zones* RBTREE_FOR(z, struct auth_zone*, &az->ztree) { lock_rw_wrlock(&z->lock); if(!auth_zone_read_zonefile(z, cfg)) { + /* For both secondary and primary zones, not fatal. + * This keeps the server up. */ + auth_zone_clear_data(z); lock_rw_unlock(&z->lock); - lock_rw_unlock(&az->lock); - return 0; + continue; } if(z->zonefile && z->zonefile[0]!=0 && env) zonemd_offline_verify(z, env, mods); @@ -1998,12 +2074,21 @@ auth_zone_get_serial(struct auth_zone* z struct auth_data* apex; struct auth_rrset* soa; struct packed_rrset_data* d; + size_t primlen, mboxlen; apex = az_find_name(z, z->name, z->namelen); if(!apex) return 0; soa = az_domain_rrset(apex, LDNS_RR_TYPE_SOA); if(!soa || soa->data->count==0) return 0; /* no RRset or no RRs in rrset */ if(soa->data->rr_len[0] < 2+4*5) return 0; /* SOA too short */ + if((primlen = dname_valid(soa->data->rr_data[0]+2, + soa->data->rr_len[0]-2)) == 0) + return 0; /* primary dname malformed */ + if((mboxlen = dname_valid(soa->data->rr_data[0]+2+primlen, + soa->data->rr_len[0]-2-primlen)) == 0) + return 0; /* mailbox dname malformed */ + if(2+primlen+mboxlen+4*5 != soa->data->rr_len[0]) + return 0; /* rdata malformed */ d = soa->data; *serial = sldns_read_uint32(d->rr_data[0]+(d->rr_len[0]-20)); return 1; @@ -2016,12 +2101,21 @@ xfr_find_soa(struct auth_zone* z, struct struct auth_data* apex; struct auth_rrset* soa; struct packed_rrset_data* d; + size_t primlen, mboxlen; apex = az_find_name(z, z->name, z->namelen); if(!apex) return 0; soa = az_domain_rrset(apex, LDNS_RR_TYPE_SOA); if(!soa || soa->data->count==0) return 0; /* no RRset or no RRs in rrset */ if(soa->data->rr_len[0] < 2+4*5) return 0; /* SOA too short */ + if((primlen = dname_valid(soa->data->rr_data[0]+2, + soa->data->rr_len[0]-2)) == 0) + return 0; /* primary dname malformed */ + if((mboxlen = dname_valid(soa->data->rr_data[0]+2+primlen, + soa->data->rr_len[0]-2-primlen)) == 0) + return 0; /* mailbox dname malformed */ + if(2+primlen+mboxlen+4*5 != soa->data->rr_len[0]) + return 0; /* rdata malformed */ /* SOA record ends with serial, refresh, retry, expiry, minimum, * as 4 byte fields */ d = soa->data; @@ -2051,6 +2145,7 @@ auth_xfer_setup(struct auth_zone* z, str if(!xfr_find_soa(z, x)) { return 1; } + x->is_rpz = (z->rpz!=NULL); /* nothing for probe, nextprobe and transfer tasks */ return 1; } @@ -2110,6 +2205,9 @@ auth_zones_cfg(struct auth_zones* az, st } return 0; } + /* Populate the xfer related options early since we may create one now */ + z->max_transfer_size = c->max_transfer_size; + z->max_transfer_time = c->max_transfer_time; if(c->masters || c->urls) { if(!(x=auth_zones_find_or_add_xfer(az, z))) { lock_rw_unlock(&az->lock); @@ -2143,7 +2241,12 @@ auth_zones_cfg(struct auth_zones* az, st z->zonemd_reject_absence = c->zonemd_reject_absence; if(c->isrpz && !z->rpz){ if(!(z->rpz = rpz_create(c))){ - fatal_exit("Could not setup RPZ zones"); + log_err("Could not setup RPZ zones"); + if(x) { + lock_basic_unlock(&x->lock); + } + lock_rw_unlock(&z->lock); + lock_rw_unlock(&az->rpz_lock); return 0; } lock_protect(&z->lock, &z->rpz->local_zones, sizeof(*z->rpz)); @@ -2181,6 +2284,10 @@ auth_zones_cfg(struct auth_zones* az, st lock_rw_unlock(&z->lock); return 0; } + /* Pick up allow notify entries, early. This works for + * addresses and netblocks. */ + if(!x->allow_notify_list) + probe_copy_masters_for_allow_notify(x); lock_basic_unlock(&x->lock); } @@ -2277,17 +2384,11 @@ static void auth_chunks_delete(struct auth_transfer* at) { if(at->chunks_first) { - struct auth_chunk* c, *cn; - c = at->chunks_first; - while(c) { - cn = c->next; - free(c->data); - free(c); - c = cn; - } + auth_chunk_list_delete(at->chunks_first); } at->chunks_first = NULL; at->chunks_last = NULL; + at->chunks_total = 0; } /** free master addr list */ @@ -2619,7 +2720,7 @@ az_empty_nonterminal(struct auth_zone* z while(next && (rbnode_type*)next != RBTREE_NULL && next->rrsets == NULL) { /* the next name has empty rrsets, is an empty nonterminal * itself, see if there exists something below it */ - next = (struct auth_data*)rbtree_next(&node->node); + next = (struct auth_data*)rbtree_next(&next->node); } if((rbnode_type*)next == RBTREE_NULL || !next) { /* there is no next node, so something below it cannot @@ -3500,7 +3601,13 @@ int auth_zones_lookup(struct auth_zones* *fallback = 1; return 0; } - if(z->zone_expired) { + if(z->zone_expired || (z->zonemd_check && z->zonemd_callback_env)) { + /* Do not serve from a zonemd-check zone while its ZONEMD + * verification is still pending: the content is not yet known + * to pass the configured check. The pending marker + * (zonemd_callback_env) is set under z->lock when the async + * lookup is spawned and cleared by the callback under z->lock, + * so this test is race-free. */ *fallback = z->fallback_enabled; lock_rw_unlock(&z->lock); return 0; @@ -3602,7 +3709,10 @@ int auth_zones_downstream_answer(struct lock_rw_unlock(&z->lock); return 0; } - if(z->zone_expired) { + if(z->zone_expired || (z->zonemd_check && z->zonemd_callback_env)) { + /* see auth_zones_lookup: a pending ZONEMD verification is + * treated like expiry - the zone content is not yet known + * to pass the configured check. */ if(z->fallback_enabled) { lock_rw_unlock(&z->lock); return 0; @@ -3990,6 +4100,22 @@ auth_master_copy(struct auth_master* o) return m; } +/** append the master to the copied list. */ +static int +auth_master_copy_and_append(struct auth_master* p, struct auth_master** list, + struct auth_master** last) +{ + struct auth_master* m = auth_master_copy(p); + if(!m) { + return 0; + } + m->next = NULL; + if(*last) (*last)->next = m; + if(!*list) *list = m; + *last = m; + return 1; +} + /** copy the master addresses from the task_probe lookups to the allow_notify * list of masters */ static void @@ -3998,17 +4124,27 @@ probe_copy_masters_for_allow_notify(stru struct auth_master* list = NULL, *last = NULL; struct auth_master* p; /* build up new list with copies */ + /* The list in task probe has been looked up before the list in + * task transfer. */ + for(p = xfr->task_probe->masters; p; p=p->next) { + if(!auth_master_copy_and_append(p, &list, &last)) { + auth_free_masters(list); + /* failed because of malloc failure, use old list */ + return; + } + } + /* The list in task transfer also contains the http entries. */ for(p = xfr->task_transfer->masters; p; p=p->next) { - struct auth_master* m = auth_master_copy(p); - if(!m) { + /* Copy the http entries from this lookup. The allow_notify + * entries are not looked up from this list. The other + * ones are already in from the probe lookups. */ + if(!p->http) + continue; + if(!auth_master_copy_and_append(p, &list, &last)) { auth_free_masters(list); /* failed because of malloc failure, use old list */ return; } - m->next = NULL; - if(last) last->next = m; - if(!list) list = m; - last = m; } /* success, replace list */ auth_free_masters(xfr->allow_notify_list); @@ -4247,7 +4383,7 @@ xfr_create_ixfr_packet(struct auth_xfer* { struct query_info qinfo; uint32_t serial; - int have_zone; + int have_zone, get_full = 0; have_zone = xfr->have_zone; serial = xfr->serial; @@ -4260,7 +4396,18 @@ xfr_create_ixfr_packet(struct auth_xfer* xfr->task_transfer->on_ixfr_is_axfr = 0; xfr->task_transfer->on_ixfr = 1; qinfo.qtype = LDNS_RR_TYPE_IXFR; - if(!have_zone || xfr->task_transfer->ixfr_fail || !master->ixfr) { + if(xfr->num_ixfrs >= NUM_IXFR_BEFORE_AXFR && xfr->is_rpz) { + /* For the RPZ, an IXFR is going to grow regions, and a + * full transfer, zonefile read, AXFR and HTTP clear the + * region, but IXFR does not. That memory keeps growing, + * and getting a full transfer with AXFR here resets that. + * The rpz->client_set->region, rpz->ns_set->region and + * rpz->respip_set->region need to be reset, they are for + * rpz-client-ip, rpz-nsip and rpz-ip. */ + get_full = 1; + } + if(!have_zone || xfr->task_transfer->ixfr_fail || !master->ixfr + || get_full) { qinfo.qtype = LDNS_RR_TYPE_AXFR; xfr->task_transfer->ixfr_fail = 0; xfr->task_transfer->on_ixfr = 0; @@ -4411,29 +4558,31 @@ chunkline_get_line(struct auth_chunk** c } /** count number of open and closed parenthesis in a chunkline */ -static int +int chunkline_count_parens(sldns_buffer* buf, size_t start) { size_t end = sldns_buffer_position(buf); size_t i; int count = 0; - int squote = 0, dquote = 0; + int dquote = 0; + char prev_c = 0; for(i=start; inum_ixfrs++; + /* start RR iterator over chunklist of packets */ chunk_rrlist_start(xfr, &rr_chunk, &rr_num, &rr_pos); while(!chunk_rrlist_end(rr_chunk, rr_num)) { @@ -5015,16 +5169,11 @@ apply_axfr(struct auth_xfer* xfr, struct size_t rr_counter = 0; int have_end_soa = 0; - /* clear the data tree */ - traverse_postorder(&z->data, auth_data_del, NULL); - rbtree_init(&z->data, &auth_data_cmp); - /* clear the RPZ policies */ - if(z->rpz) - rpz_clear(z->rpz); - + auth_zone_clear_data(z); xfr->have_zone = 0; xfr->serial = 0; xfr->soa_zone_acquired = 0; + xfr->num_ixfrs = 0; /* insert all RRs in to the zone */ /* insert the SOA only once, skip the last one */ @@ -5117,16 +5266,11 @@ apply_http(struct auth_xfer* xfr, struct return 0; } - /* clear the data tree */ - traverse_postorder(&z->data, auth_data_del, NULL); - rbtree_init(&z->data, &auth_data_cmp); - /* clear the RPZ policies */ - if(z->rpz) - rpz_clear(z->rpz); - + auth_zone_clear_data(z); xfr->have_zone = 0; xfr->serial = 0; xfr->soa_zone_acquired = 0; + xfr->num_ixfrs = 0; chunk = xfr->task_transfer->chunks_first; chunk_pos = 0; @@ -5172,7 +5316,7 @@ apply_http(struct auth_xfer* xfr, struct /** write http chunks to zonefile to create downloaded file */ static int -auth_zone_write_chunks(struct auth_xfer* xfr, const char* fname) +auth_zone_write_chunks(struct auth_chunk* chunk_list, const char* fname) { FILE* out; struct auth_chunk* p; @@ -5181,7 +5325,7 @@ auth_zone_write_chunks(struct auth_xfer* log_err("could not open %s: %s", fname, strerror(errno)); return 0; } - for(p = xfr->task_transfer->chunks_first; p ; p = p->next) { + for(p = chunk_list; p ; p = p->next) { if(!write_out(out, (char*)p->data, p->len)) { log_err("could not write http download to %s", fname); fclose(out); @@ -5192,34 +5336,18 @@ auth_zone_write_chunks(struct auth_xfer* return 1; } -/** write to zonefile after zone has been updated */ +/** write to zonefile after zone has been updated, z has rdlock by caller. */ static void -xfr_write_after_update(struct auth_xfer* xfr, struct module_env* env) +zone_write_after_update(struct auth_zone* z, struct module_env* env, + struct auth_chunk* chunk_list) { struct config_file* cfg = env->cfg; - struct auth_zone* z; char tmpfile[1024]; char* zfilename; - lock_basic_unlock(&xfr->lock); - - /* get lock again, so it is a readlock and concurrently queries - * can be answered */ - lock_rw_rdlock(&env->auth_zones->lock); - z = auth_zone_find(env->auth_zones, xfr->name, xfr->namelen, - xfr->dclass); - if(!z) { - lock_rw_unlock(&env->auth_zones->lock); - /* the zone is gone, ignore xfr results */ - lock_basic_lock(&xfr->lock); - return; - } - lock_rw_rdlock(&z->lock); - lock_basic_lock(&xfr->lock); - lock_rw_unlock(&env->auth_zones->lock); if(z->zonefile == NULL || z->zonefile[0] == 0) { - lock_rw_unlock(&z->lock); /* no write needed, no zonefile set */ + auth_chunk_list_delete(chunk_list); return; } zfilename = z->zonefile; @@ -5236,21 +5364,21 @@ xfr_write_after_update(struct auth_xfer* if((size_t)strlen(zfilename) + 16 > sizeof(tmpfile)) { verbose(VERB_ALGO, "tmpfilename too long, cannot update " " zonefile %s", zfilename); - lock_rw_unlock(&z->lock); + auth_chunk_list_delete(chunk_list); return; } snprintf(tmpfile, sizeof(tmpfile), "%s.tmp%u", zfilename, (unsigned)getpid()); - if(xfr->task_transfer->master->http) { + if(chunk_list) { /* use the stored chunk list to write them */ - if(!auth_zone_write_chunks(xfr, tmpfile)) { + if(!auth_zone_write_chunks(chunk_list, tmpfile)) { unlink(tmpfile); - lock_rw_unlock(&z->lock); + auth_chunk_list_delete(chunk_list); return; } + auth_chunk_list_delete(chunk_list); } else if(!auth_zone_write_file(z, tmpfile)) { unlink(tmpfile); - lock_rw_unlock(&z->lock); return; } #ifdef UB_ON_WINDOWS @@ -5260,9 +5388,57 @@ xfr_write_after_update(struct auth_xfer* log_err("could not rename(%s, %s): %s", tmpfile, zfilename, strerror(errno)); unlink(tmpfile); - lock_rw_unlock(&z->lock); return; } +} + +/** write to zonefile after zone has updated, reacquires z readlock. */ +static void +zone_write_after_update_reacq(uint8_t* bakname, size_t baknamelen, + uint16_t bakdclass, struct module_env* env, + struct auth_chunk* chunk_list) +{ + struct auth_zone* z; + /* get lock again, so it is a readlock and concurrently queries + * can be answered */ + lock_rw_rdlock(&env->auth_zones->lock); + z = auth_zone_find(env->auth_zones, bakname, baknamelen, bakdclass); + if(!z) { + lock_rw_unlock(&env->auth_zones->lock); + /* the zone is gone, ignore xfr results */ + return; + } + lock_rw_rdlock(&z->lock); + lock_rw_unlock(&env->auth_zones->lock); + + zone_write_after_update(z, env, chunk_list); + lock_rw_unlock(&z->lock); +} + +/** write to zonefile after zone has been updated */ +static void +xfr_write_after_update(struct auth_xfer* xfr, struct module_env* env, + struct auth_chunk* chunk_list) +{ + struct auth_zone* z; + lock_basic_unlock(&xfr->lock); + + /* get lock again, so it is a readlock and concurrently queries + * can be answered */ + lock_rw_rdlock(&env->auth_zones->lock); + z = auth_zone_find(env->auth_zones, xfr->name, xfr->namelen, + xfr->dclass); + if(!z) { + lock_rw_unlock(&env->auth_zones->lock); + /* the zone is gone, ignore xfr results */ + lock_basic_lock(&xfr->lock); + return; + } + lock_rw_rdlock(&z->lock); + lock_basic_lock(&xfr->lock); + lock_rw_unlock(&env->auth_zones->lock); + + zone_write_after_update(z, env, chunk_list); lock_rw_unlock(&z->lock); } @@ -5295,6 +5471,8 @@ xfr_process_chunk_list(struct auth_xfer* int* ixfr_fail) { struct auth_zone* z; + int zonemd_in_progress; + struct auth_chunk* current_chunk_list = NULL; /* obtain locks and structures */ lock_basic_unlock(&xfr->lock); @@ -5307,6 +5485,7 @@ xfr_process_chunk_list(struct auth_xfer* /* apply data */ if(xfr->task_transfer->master->http) { if(!apply_http(xfr, z, env->scratch_buffer)) { + auth_zone_clear_data(z); lock_rw_unlock(&z->lock); verbose(VERB_ALGO, "http from %s: could not store data", xfr->task_transfer->master->host); @@ -5315,6 +5494,7 @@ xfr_process_chunk_list(struct auth_xfer* } else if(xfr->task_transfer->on_ixfr && !xfr->task_transfer->on_ixfr_is_axfr) { if(!apply_ixfr(xfr, z, env->scratch_buffer)) { + auth_zone_clear_data(z); lock_rw_unlock(&z->lock); verbose(VERB_ALGO, "xfr from %s: could not store IXFR" " data", xfr->task_transfer->master->host); @@ -5323,6 +5503,7 @@ xfr_process_chunk_list(struct auth_xfer* } } else { if(!apply_axfr(xfr, z, env->scratch_buffer)) { + auth_zone_clear_data(z); lock_rw_unlock(&z->lock); verbose(VERB_ALGO, "xfr from %s: could not store AXFR" " data", xfr->task_transfer->master->host); @@ -5339,6 +5520,7 @@ xfr_process_chunk_list(struct auth_xfer* } z->soa_zone_acquired = *env->now; xfr->soa_zone_acquired = *env->now; + xfr->is_rpz = (z->rpz!=NULL); /* release xfr lock while verifying zonemd because it may have * to spawn lookups in the state machines */ @@ -5374,6 +5556,25 @@ xfr_process_chunk_list(struct auth_xfer* if(z->rpz) rpz_finish_config(z->rpz); + if(z->zonemd_check && z->zonemd_callback_env) { + zonemd_in_progress = 1; + z->zonemd_callback_perform_write = 1; + auth_chunk_list_delete(z->perform_write_chunk_list); + z->perform_write_chunk_list = NULL; + if(xfr->task_transfer->master->http) { + z->perform_write_chunk_list = xfr->task_transfer->chunks_first; + xfr->task_transfer->chunks_first = NULL; + auth_chunks_delete(xfr->task_transfer); + } + } else { + zonemd_in_progress = 0; + z->zonemd_callback_perform_write = 0; + if(xfr->task_transfer->master->http) { + current_chunk_list = xfr->task_transfer->chunks_first; + xfr->task_transfer->chunks_first = NULL; + auth_chunks_delete(xfr->task_transfer); + } + } /* unlock */ lock_rw_unlock(&z->lock); @@ -5384,20 +5585,56 @@ xfr_process_chunk_list(struct auth_xfer* (unsigned)xfr->serial); } /* see if we need to write to a zonefile */ - xfr_write_after_update(xfr, env); + if(!zonemd_in_progress) { + xfr_write_after_update(xfr, env, current_chunk_list); + } return 1; } +/** Stop lookup using callback */ +static void +xfr_stop_lookup(struct auth_master** lookup_target, void* lookup_unique_info, + int lookup_aaaa, uint16_t dclass, struct mesh_area* mesh, + mesh_cb_func_type cb, void* cb_arg) +{ + struct query_info qinfo; + uint8_t dname[LDNS_MAX_DOMAINLEN+1]; + if(!*lookup_target) return; + qinfo.qname_len = sizeof(dname); + if(sldns_str2wire_dname_buf((*lookup_target)->host, dname, + &qinfo.qname_len) != 0) { + *lookup_target = NULL; + return; + } + qinfo.qname = dname; + qinfo.qclass = dclass; + qinfo.qtype = lookup_aaaa ? LDNS_RR_TYPE_AAAA : LDNS_RR_TYPE_A; + qinfo.local_alias = NULL; + log_query_info(VERB_ALGO, "removing xfr callback", &qinfo); + + mesh_remove_callback(mesh, &qinfo, BIT_RD, cb, cb_arg, + lookup_unique_info); + *lookup_target = NULL; +} + /** disown task_transfer. caller must hold xfr.lock */ static void xfr_transfer_disown(struct auth_xfer* xfr) { + /* remove data chunks */ + auth_chunks_delete(xfr->task_transfer); /* remove timer (from this worker's event base) */ comm_timer_delete(xfr->task_transfer->timer); xfr->task_transfer->timer = NULL; /* remove the commpoint */ comm_point_delete(xfr->task_transfer->cp); xfr->task_transfer->cp = NULL; + if(xfr->task_transfer->env) + xfr_stop_lookup(&xfr->task_transfer->lookup_target, + xfr->task_transfer->lookup_unique_info, + xfr->task_transfer->lookup_aaaa, xfr->dclass, + xfr->task_transfer->env->mesh, + &auth_xfer_transfer_lookup_callback, xfr); /* we don't own this item anymore */ xfr->task_transfer->worker = NULL; xfr->task_transfer->env = NULL; @@ -5464,7 +5701,8 @@ xfr_transfer_lookup_host(struct auth_xfe * called straight away */ lock_basic_unlock(&xfr->lock); if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0, - &auth_xfer_transfer_lookup_callback, xfr, 0)) { + &auth_xfer_transfer_lookup_callback, xfr, 0, + &xfr->task_transfer->lookup_unique_info)) { lock_basic_lock(&xfr->lock); log_err("out of memory lookup up master %s", master->host); return 0; @@ -5522,6 +5760,7 @@ xfr_transfer_init_fetch(struct auth_xfer t.tv_sec = timeout/1000; t.tv_usec = (timeout%1000)*1000; #endif + xfr->task_transfer->start_time = *env->now_tv; if(master->http) { /* perform http fetch */ @@ -5691,10 +5930,34 @@ xfr_master_add_addrs(struct auth_master* } } +/** check if the lookup target name equals the found answer name. */ +static int +xfer_target_equals_answer_name(struct auth_master* lookup_target, + struct ub_packed_rrset_key* answer, struct query_info* rq, + struct reply_info* rep) +{ + uint8_t qname[LDNS_MAX_DOMAINLEN+1]; + size_t qname_len; + if(!lookup_target) return 0; + if(!answer) return 0; + qname_len = sizeof(qname); + if(sldns_str2wire_dname_buf(lookup_target->host, qname, &qname_len) + != 0) { + verbose(VERB_ALGO, "xfer_target_equals_answer_name: could not parse auth host name"); + return 0; + } + if(query_dname_compare(answer->rk.dname, qname) == 0) + return 1; + /* It could be a CNAME. */ + if(reply_find_rrset_section_an(rep, qname, qname_len, + LDNS_RR_TYPE_CNAME, rq->qclass)) + return 1; + return 0; +} + /** callback for task_transfer lookup of host name, of A or AAAA */ void auth_xfer_transfer_lookup_callback(void* arg, int rcode, sldns_buffer* buf, - enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus), - int ATTR_UNUSED(was_ratelimited)) + enum sec_status sec, char* why_bogus, int ATTR_UNUSED(was_ratelimited)) { struct auth_xfer* xfr = (struct auth_xfer*)arg; struct module_env* env; @@ -5707,7 +5970,16 @@ void auth_xfer_transfer_lookup_callback( } /* process result */ - if(rcode == LDNS_RCODE_NOERROR) { + if(sec == sec_status_bogus || sec == sec_status_secure_sentinel_fail) { + if(verbosity >= VERB_OPS) { + char zname[LDNS_MAX_DOMAINLEN]; + dname_str(xfr->name, zname); + verbose(VERB_OPS, "auth zone %s: primary %s address lookup is DNSSEC bogus: %s", + zname, xfr->task_transfer->lookup_target->host, + (why_bogus?why_bogus:"")); + } + /* fall through to next-lookup / next-master */ + } else if(rcode == LDNS_RCODE_NOERROR) { uint16_t wanted_qtype = LDNS_RR_TYPE_A; struct regional* temp = env->scratch; struct query_info rq; @@ -5721,21 +5993,29 @@ void auth_xfer_transfer_lookup_callback( /* parsed successfully */ struct ub_packed_rrset_key* answer = reply_find_answer_rrset(&rq, rep); - if(answer) { + if(answer && xfer_target_equals_answer_name( + xfr->task_transfer->lookup_target, answer, + &rq, rep)) { xfr_master_add_addrs(xfr->task_transfer-> lookup_target, answer, wanted_qtype); + } else if(answer) { + if(verbosity >= VERB_ALGO) { + char zname[LDNS_MAX_DOMAINLEN]; + dname_str(xfr->name, zname); + verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup has mismatch in answer name", zname, ((xfr->task_transfer->lookup_target && xfr->task_transfer->lookup_target->host) ? xfr->task_transfer->lookup_target->host : "null"), (xfr->task_transfer->lookup_aaaa?"AAAA":"A")); + } } else { if(verbosity >= VERB_ALGO) { 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")); + verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup has nodata", zname, ((xfr->task_transfer->lookup_target && xfr->task_transfer->lookup_target->host) ? xfr->task_transfer->lookup_target->host : "null"), (xfr->task_transfer->lookup_aaaa?"AAAA":"A")); } } } else { if(verbosity >= VERB_ALGO) { 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")); + verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup has no answer", zname, ((xfr->task_transfer->lookup_target && xfr->task_transfer->lookup_target->host) ? xfr->task_transfer->lookup_target->host : "null"), (xfr->task_transfer->lookup_aaaa?"AAAA":"A")); } } regional_free_all(temp); @@ -5743,10 +6023,11 @@ void auth_xfer_transfer_lookup_callback( if(verbosity >= VERB_ALGO) { 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")); + verbose(VERB_ALGO, "auth zone %s host %s type %s transfer lookup failed", zname, ((xfr->task_transfer->lookup_target && xfr->task_transfer->lookup_target->host) ? xfr->task_transfer->lookup_target->host : "null"), (xfr->task_transfer->lookup_aaaa?"AAAA":"A")); } } - if(xfr->task_transfer->lookup_target->list && + if(xfr->task_transfer->lookup_target && + xfr->task_transfer->lookup_target->list && xfr->task_transfer->lookup_target == xfr_transfer_current_master(xfr)) xfr->task_transfer->scan_addr = xfr->task_transfer->lookup_target->list; @@ -6076,6 +6357,7 @@ xfer_link_data(sldns_buffer* pkt, struct if(xfr->task_transfer->chunks_last) xfr->task_transfer->chunks_last->next = e; xfr->task_transfer->chunks_last = e; + xfr->task_transfer->chunks_total += e->len; return 1; } @@ -6171,6 +6453,15 @@ auth_xfer_transfer_timer_callback(void* xfr_transfer_nexttarget_or_end(xfr, env); } +/** return the time taken by the transfer */ +static int +auth_xfer_transfer_time_taken(struct auth_xfer* xfr, struct module_env* env) +{ + struct timeval delta; + timeval_subtract(&delta, env->now_tv, &xfr->task_transfer->start_time); + return ((int)delta.tv_sec)*1000 + ((int)delta.tv_usec)/1000; +} + /** callback for task_transfer tcp connections */ int auth_xfer_transfer_tcp_callback(struct comm_point* c, void* arg, int err, @@ -6237,6 +6528,15 @@ auth_xfer_transfer_tcp_callback(struct c xfr->task_transfer->master->host); goto failed; } + if(xfr->max_transfer_size > 0 && + xfr->task_transfer->chunks_total > xfr->max_transfer_size) { + char zname[LDNS_MAX_DOMAINLEN]; + dname_str(xfr->name, zname); + log_err("auth zone %s transfer from %s exceeded %u bytes, aborting", + zname, xfr->task_transfer->master->host, + (unsigned)xfr->max_transfer_size); + goto failed; + } /* if the transfer is done now, disconnect and process the list */ if(transferdone) { comm_point_delete(xfr->task_transfer->cp); @@ -6245,6 +6545,16 @@ auth_xfer_transfer_tcp_callback(struct c return 0; } + if(xfr->max_transfer_time > 0 && + auth_xfer_transfer_time_taken(xfr, env) > xfr->max_transfer_time) { + char zname[LDNS_MAX_DOMAINLEN]; + dname_str(xfr->name, zname); + log_err("auth zone %s transfer from %s exceeded %u msec total running time, aborting", + zname, xfr->task_transfer->master->host, + (unsigned)xfr->max_transfer_time); + goto failed; + } + /* if we want to read more messages, setup the commpoint to read * a DNS packet, and the timeout */ lock_basic_unlock(&xfr->lock); @@ -6300,6 +6610,16 @@ auth_xfer_transfer_http_callback(struct xfr->task_transfer->master->host); goto failed; } + if(xfr->max_transfer_size > 0 && + xfr->task_transfer->chunks_total > xfr->max_transfer_size) { + char zname[LDNS_MAX_DOMAINLEN]; + dname_str(xfr->name, zname); + log_err("auth zone %s http %s/%s exceeded %u bytes, aborting", + zname, xfr->task_transfer->master->host, + xfr->task_transfer->master->file, + (unsigned)xfr->max_transfer_size); + goto failed; + } } /* if the transfer is done now, disconnect and process the list */ if(err == NETEVENT_DONE) { @@ -6311,6 +6631,17 @@ auth_xfer_transfer_http_callback(struct return 0; } + if(xfr->max_transfer_time > 0 && + auth_xfer_transfer_time_taken(xfr, env) > xfr->max_transfer_time) { + char zname[LDNS_MAX_DOMAINLEN]; + dname_str(xfr->name, zname); + log_err("auth zone %s transfer http %s/%s exceeded %u msec total running time, aborting", + zname, xfr->task_transfer->master->host, + xfr->task_transfer->master->file, + (unsigned)xfr->max_transfer_time); + goto failed; + } + /* if we want to read more messages, setup the commpoint to read * a DNS packet, and the timeout */ lock_basic_unlock(&xfr->lock); @@ -6353,6 +6684,12 @@ xfr_probe_disown(struct auth_xfer* xfr) /* remove the commpoint */ comm_point_delete(xfr->task_probe->cp); xfr->task_probe->cp = NULL; + if(xfr->task_probe->env) + xfr_stop_lookup(&xfr->task_probe->lookup_target, + xfr->task_probe->lookup_unique_info, + xfr->task_probe->lookup_aaaa, xfr->dclass, + xfr->task_probe->env->mesh, + &auth_xfer_probe_lookup_callback, xfr); /* we don't own this item anymore */ xfr->task_probe->worker = NULL; xfr->task_probe->env = NULL; @@ -6659,7 +6996,8 @@ xfr_probe_lookup_host(struct auth_xfer* * called straight away */ lock_basic_unlock(&xfr->lock); if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0, - &auth_xfer_probe_lookup_callback, xfr, 0)) { + &auth_xfer_probe_lookup_callback, xfr, 0, + &xfr->task_probe->lookup_unique_info)) { lock_basic_lock(&xfr->lock); log_err("out of memory lookup up master %s", master->host); return 0; @@ -6668,6 +7006,18 @@ xfr_probe_lookup_host(struct auth_xfer* return 1; } +/** return true if there are probe (SOA UDP query) targets in the master list*/ +static int +have_probe_targets(struct auth_master* list) +{ + struct auth_master* p; + for(p=list; p; p = p->next) { + if(!p->allow_notify && p->host) + return 1; + } + return 0; +} + /** move to sending the probe packets, next if fails. task_probe */ static void xfr_probe_send_or_end(struct auth_xfer* xfr, struct module_env* env) @@ -6707,6 +7057,16 @@ xfr_probe_send_or_end(struct auth_xfer* verbose(VERB_ALGO, "auth zone %s probe: finished only_lookup", zname); } xfr_probe_disown(xfr); + if(!have_probe_targets(xfr->task_probe->masters)) { + /* If there are no masters to probe, go to transfer. */ + if(xfr->task_transfer->worker == NULL) { + xfr_start_transfer(xfr, env, NULL); + return; + } + /* The transfer is already in progress. */ + lock_basic_unlock(&xfr->lock); + return; + } if(xfr->task_nextprobe->worker == NULL) xfr_set_timeout(xfr, env, 0, 0); lock_basic_unlock(&xfr->lock); @@ -6756,8 +7116,7 @@ xfr_probe_send_or_end(struct auth_xfer* /** callback for task_probe lookup of host name, of A or AAAA */ void auth_xfer_probe_lookup_callback(void* arg, int rcode, sldns_buffer* buf, - enum sec_status ATTR_UNUSED(sec), char* ATTR_UNUSED(why_bogus), - int ATTR_UNUSED(was_ratelimited)) + enum sec_status sec, char* why_bogus, int ATTR_UNUSED(was_ratelimited)) { struct auth_xfer* xfr = (struct auth_xfer*)arg; struct module_env* env; @@ -6770,7 +7129,16 @@ void auth_xfer_probe_lookup_callback(voi } /* process result */ - if(rcode == LDNS_RCODE_NOERROR) { + if(sec == sec_status_bogus || sec == sec_status_secure_sentinel_fail) { + if(verbosity >= VERB_OPS) { + char zname[LDNS_MAX_DOMAINLEN]; + dname_str(xfr->name, zname); + verbose(VERB_OPS, "auth zone %s: primary %s address probe lookup is DNSSEC bogus: %s", + zname, xfr->task_probe->lookup_target->host, + (why_bogus?why_bogus:"")); + } + /* fall through to next-lookup / next-master */ + } else if(rcode == LDNS_RCODE_NOERROR) { uint16_t wanted_qtype = LDNS_RR_TYPE_A; struct regional* temp = env->scratch; struct query_info rq; @@ -6784,21 +7152,29 @@ void auth_xfer_probe_lookup_callback(voi /* parsed successfully */ struct ub_packed_rrset_key* answer = reply_find_answer_rrset(&rq, rep); - if(answer) { + if(answer && xfer_target_equals_answer_name( + xfr->task_probe->lookup_target, answer, + &rq, rep)) { xfr_master_add_addrs(xfr->task_probe-> lookup_target, answer, wanted_qtype); + } else if(answer) { + if(verbosity >= VERB_ALGO) { + char zname[LDNS_MAX_DOMAINLEN]; + dname_str(xfr->name, zname); + verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup has mismatch in answer name", zname, ((xfr->task_probe->lookup_target && xfr->task_probe->lookup_target->host) ? xfr->task_probe->lookup_target->host : "null"), (xfr->task_probe->lookup_aaaa?"AAAA":"A")); + } } else { if(verbosity >= VERB_ALGO) { 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")); + verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup has nodata", zname, ((xfr->task_probe->lookup_target && xfr->task_probe->lookup_target->host) ? xfr->task_probe->lookup_target->host : "null"), (xfr->task_probe->lookup_aaaa?"AAAA":"A")); } } } else { if(verbosity >= VERB_ALGO) { 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")); + verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup has no address", zname, ((xfr->task_probe->lookup_target && xfr->task_probe->lookup_target->host) ? xfr->task_probe->lookup_target->host : "null"), (xfr->task_probe->lookup_aaaa?"AAAA":"A")); } } regional_free_all(temp); @@ -6806,10 +7182,11 @@ void auth_xfer_probe_lookup_callback(voi if(verbosity >= VERB_ALGO) { 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")); + verbose(VERB_ALGO, "auth zone %s host %s type %s probe lookup failed", zname, ((xfr->task_probe->lookup_target && xfr->task_probe->lookup_target->host) ? xfr->task_probe->lookup_target->host : "null"), (xfr->task_probe->lookup_aaaa?"AAAA":"A")); } } - if(xfr->task_probe->lookup_target->list && + if(xfr->task_probe->lookup_target && + xfr->task_probe->lookup_target->list && xfr->task_probe->lookup_target == xfr_probe_current_master(xfr)) xfr->task_probe->scan_addr = xfr->task_probe->lookup_target->list; @@ -6863,18 +7240,6 @@ auth_xfer_timer(void* arg) } } -/** return true if there are probe (SOA UDP query) targets in the master list*/ -static int -have_probe_targets(struct auth_master* list) -{ - struct auth_master* p; - for(p=list; p; p = p->next) { - if(!p->allow_notify && p->host) - return 1; - } - return 0; -} - /** start task_probe if possible, if no masters for probe start task_transfer * returns true if task has been started, and false if the task is already * in progress. */ @@ -6886,8 +7251,10 @@ xfr_start_probe(struct auth_xfer* xfr, s * progress (due to notify)) */ if(xfr->task_probe->worker == NULL) { if(!have_probe_targets(xfr->task_probe->masters) && - !(xfr->task_probe->only_lookup && - xfr->task_probe->masters != NULL)) { + xfr->task_probe->masters != NULL) + xfr->task_probe->only_lookup = 1; + if(!xfr->task_probe->only_lookup && + !have_probe_targets(xfr->task_probe->masters)) { /* useless to pick up task_probe, no masters to * probe. Instead attempt to pick up task transfer */ if(xfr->task_transfer->worker == NULL) { @@ -7090,6 +7457,8 @@ auth_xfer_new(struct auth_zone* z) xfr->namelen = z->namelen; xfr->namelabs = z->namelabs; xfr->dclass = z->dclass; + xfr->max_transfer_size = z->max_transfer_size; + xfr->max_transfer_time = z->max_transfer_time; xfr->task_nextprobe = (struct auth_nextprobe*)calloc(1, sizeof(struct auth_nextprobe)); @@ -7299,35 +7668,48 @@ xfer_set_masters(struct auth_master** li { struct auth_master* m; struct config_strlist* p; + struct auth_master** tail; /* list points to the first, or next pointer for the new element */ while(*list) { list = &( (*list)->next ); } if(with_http) for(p = c->urls; p; p = p->next) { + tail = list; m = auth_master_new(&list); if(!m) return 0; m->http = 1; - if(!parse_url(p->str, &m->host, &m->file, &m->port, &m->ssl)) + if(!parse_url(p->str, &m->host, &m->file, &m->port, &m->ssl)) { + free(m->host); + free(m->file); + free(m); + *tail = NULL; return 0; + } } for(p = c->masters; p; p = p->next) { + tail = list; m = auth_master_new(&list); if(!m) return 0; m->ixfr = 1; /* this flag is not configurable */ m->host = strdup(p->str); if(!m->host) { log_err("malloc failure"); + free(m); + *tail = NULL; return 0; } } for(p = c->allow_notify; p; p = p->next) { + tail = list; m = auth_master_new(&list); if(!m) return 0; m->allow_notify = 1; m->host = strdup(p->str); if(!m->host) { log_err("malloc failure"); + free(m); + *tail = NULL; return 0; } } @@ -7852,7 +8234,8 @@ static int zonemd_dnssec_verify_rrset(st "zonemd: verify %s RRset with DNSKEY", typestr); } sec = dnskeyset_verify_rrset(env, ve, &pk, dnskey, sigalg, why_bogus, NULL, - LDNS_SECTION_ANSWER, NULL, &verified, reasonbuf, reasonlen); + LDNS_SECTION_ANSWER, NULL, NULL, &verified, reasonbuf, + reasonlen); if(sec == sec_status_secure) { return 1; } @@ -8201,8 +8584,8 @@ zonemd_get_dnskey_from_anchor(struct aut auth_zone_log(z->name, VERB_QUERY, "zonemd: verify DNSKEY RRset with trust anchor"); sec = val_verify_DNSKEY_with_TA(env, ve, keystorage, anchor->ds_rrset, - anchor->dnskey_rrset, NULL, why_bogus, NULL, NULL, reasonbuf, - reasonlen); + anchor->dnskey_rrset, NULL, why_bogus, NULL, NULL, NULL, + reasonbuf, reasonlen); regional_free_all(env->scratch); if(sec == sec_status_secure) { /* success */ @@ -8262,7 +8645,7 @@ auth_zone_verify_zonemd_key_with_ds(stru keystorage->rk.rrset_class = htons(z->dclass); auth_zone_log(z->name, VERB_QUERY, "zonemd: verify zone DNSKEY with DS"); sec = val_verify_DNSKEY_with_DS(env, ve, keystorage, ds, sigalg, - why_bogus, NULL, NULL, reasonbuf, reasonlen); + why_bogus, NULL, NULL, NULL, reasonbuf, reasonlen); regional_free_all(env->scratch); if(sec == sec_status_secure) { /* success */ @@ -8291,9 +8674,13 @@ void auth_zonemd_dnskey_lookup_callback( char reasonbuf[256]; char* reason = NULL, *ds_bogus = NULL, *typestr="DNSKEY"; struct ub_packed_rrset_key* dnskey = NULL, *ds = NULL; - int is_insecure = 0, downprot; + int is_insecure = 0, downprot, perform_write = 0; struct ub_packed_rrset_key keystorage; uint8_t sigalg[ALGO_NEEDS_MAX+1]; + uint8_t bakname[LDNS_MAX_DOMAINLEN]; + size_t baknamelen; + uint16_t bakdclass; + struct auth_chunk* chunk_list = NULL; lock_rw_wrlock(&z->lock); env = z->zonemd_callback_env; @@ -8416,7 +8803,37 @@ void auth_zonemd_dnskey_lookup_callback( auth_zone_verify_zonemd_with_key(z, env, &env->mesh->mods, dnskey, is_insecure, NULL, downprot?sigalg:NULL); regional_free_all(env->scratch); + + if(z->zonemd_callback_perform_write) { + if(!z->zone_expired) { + /* Write to zonefile if the ZONEMD is okay. */ + perform_write = 1; + /* copy the key to lookup the z structure. + * The new lookup is readonly so concurrent + * queries can continue. */ + if(z->namelen > sizeof(bakname)) { + perform_write = 0; + auth_chunk_list_delete(z->perform_write_chunk_list); + z->perform_write_chunk_list = NULL; + } else { + memcpy(bakname, z->name, z->namelen); + baknamelen = z->namelen; + bakdclass = z->dclass; + chunk_list = z->perform_write_chunk_list; + z->perform_write_chunk_list = NULL; + } + } else { + auth_chunk_list_delete(z->perform_write_chunk_list); + z->perform_write_chunk_list = NULL; + } + z->zonemd_callback_perform_write = 0; + } lock_rw_unlock(&z->lock); + + if(perform_write) { + zone_write_after_update_reacq(bakname, baknamelen, bakdclass, + env, chunk_list); + } } /** lookup DNSKEY for ZONEMD verification */ @@ -8481,8 +8898,12 @@ zonemd_lookup_dnskey(struct auth_zone* z /* the callback can be called straight away */ lock_rw_unlock(&z->lock); if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0, - &auth_zonemd_dnskey_lookup_callback, z, 0)) { + &auth_zonemd_dnskey_lookup_callback, z, 0, + &z->zonemd_callback_unique_info)) { lock_rw_wrlock(&z->lock); + /* no callback will run; do not leave the pending + * marker set */ + z->zonemd_callback_env = NULL; log_err("out of memory lookup of %s for zonemd", (fetch_ds?"DS":"DNSKEY")); return 0; Index: sbin/unwind/libunbound/services/authzone.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/services/authzone.h,v diff -u -p -r1.10 authzone.h --- sbin/unwind/libunbound/services/authzone.h 29 Sep 2025 14:53:38 -0000 1.10 +++ sbin/unwind/libunbound/services/authzone.h 21 Sep 2026 16:28:24 -0000 @@ -144,6 +144,12 @@ struct auth_zone { struct module_env* zonemd_callback_env; /** for the zonemd callback, the type of data looked up */ uint16_t zonemd_callback_qtype; + /** for the zonemd callback, the unique info */ + void* zonemd_callback_unique_info; + /** if the zonemd callback should write to file */ + int zonemd_callback_perform_write; + /** chunklist to write for chunked transfer. */ + struct auth_chunk* perform_write_chunk_list; /** zone has been deleted */ int zone_deleted; /** deletelist pointer, unused normally except during delete */ @@ -153,6 +159,10 @@ struct auth_zone { struct auth_zone* rpz_az_next; /** previous auth zone containing RPZ data, or NULL */ struct auth_zone* rpz_az_prev; + /** The maximum auth zone transfer size, in bytes. */ + size_t max_transfer_size; + /** The maximum auth zone transfer time taken, in msec. */ + int max_transfer_time; }; /** @@ -283,6 +293,15 @@ struct auth_xfer { * this is renewed every SOA probe and transfer. On zone load * from zonefile it is also set (with probe set soon to check) */ time_t lease_time; + + /** The maximum auth zone transfer size, in bytes. */ + size_t max_transfer_size; + /** The maximum auth zone transfer time taken, in msec. */ + int max_transfer_time; + /** the zone is an rpz zone */ + int is_rpz; + /** the number of IXFRs since the last full transfer. */ + int num_ixfrs; }; /** @@ -331,6 +350,8 @@ struct auth_probe { /** for the hostname lookups, which master is current */ struct auth_master* lookup_target; + /** for the lookup, the callback unique info */ + void* lookup_unique_info; /** are we looking up A or AAAA, first A, then AAAA (if ip6 enabled) */ int lookup_aaaa; /** we only want to do lookups for making config work (for notify), @@ -379,12 +400,18 @@ struct auth_transfer { struct auth_chunk* chunks_first; /** last element in chunks list (to append new data at the end) */ struct auth_chunk* chunks_last; + /** running total of bytes held in chunks_first..chunks_last */ + size_t chunks_total; + /** start time of the transfer */ + struct timeval start_time; /** list of upstream masters for this zone, from config */ struct auth_master* masters; /** for the hostname lookups, which master is current */ struct auth_master* lookup_target; + /** for the lookup, the callback unique info */ + void* lookup_unique_info; /** are we looking up A or AAAA, first A, then AAAA (if ip6 enabled) */ int lookup_aaaa; @@ -827,5 +854,11 @@ void auth_xfer_delete(struct auth_xfer* * @param worker: the worker for which to stop tasks. */ void xfr_disown_tasks(struct auth_xfer* xfr, struct worker* worker); + +/** count number of open and closed parenthesis in a chunkline */ +int chunkline_count_parens(struct sldns_buffer* buf, size_t start); + +/** Clear data in auth zone */ +void auth_zone_clear_data(struct auth_zone* z); #endif /* SERVICES_AUTHZONE_H */ Index: sbin/unwind/libunbound/services/listen_dnsport.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/services/listen_dnsport.c,v diff -u -p -r1.21 listen_dnsport.c --- sbin/unwind/libunbound/services/listen_dnsport.c 29 Sep 2025 14:53:38 -0000 1.21 +++ sbin/unwind/libunbound/services/listen_dnsport.c 21 Sep 2026 16:28:24 -0000 @@ -42,7 +42,6 @@ #ifdef HAVE_SYS_TYPES_H # include #endif -#include #include #ifdef USE_TCP_FASTOPEN #include @@ -1126,7 +1125,7 @@ make_sock_port(int stype, const char* if int use_systemd, int dscp, struct unbound_socket* ub_sock, const char* additional) { - char* s = strchr(ifname, '@'); + const char* s = strchr(ifname, '@'); if(s) { /* override port with ifspec@port */ int port; @@ -1564,7 +1563,7 @@ listen_create(struct comm_base* base, st cp = comm_point_create_udp(base, ports->fd, front->udp_buff, ports->pp2_enabled, cb, cb_arg, ports->socket); - } else if(ports->ftype == listen_type_doq) { + } else if(ports->ftype == listen_type_doq && doq_table) { #ifndef HAVE_NGTCP2 log_warn("Unbound is not compiled with " "ngtcp2. This is required to use DNS " @@ -2134,7 +2133,7 @@ void listen_start_accept(struct listen_d } struct tcp_req_info* -tcp_req_info_create(struct sldns_buffer* spoolbuf) +tcp_req_info_create(struct comm_base* base, struct sldns_buffer* spoolbuf) { struct tcp_req_info* req = (struct tcp_req_info*)malloc(sizeof(*req)); if(!req) { @@ -2142,6 +2141,12 @@ tcp_req_info_create(struct sldns_buffer* return NULL; } memset(req, 0, sizeof(*req)); + req->read_again_timer = comm_timer_create(base, tcp_read_again_cb, req); + if(!req->read_again_timer) { + log_err("malloc failure"); + free(req); + return NULL; + } req->spool_buffer = spoolbuf; return req; } @@ -2151,6 +2156,7 @@ tcp_req_info_delete(struct tcp_req_info* { if(!req) return; tcp_req_info_clear(req); + comm_timer_delete(req->read_again_timer); /* cp is pointer back to commpoint that owns this struct and * called delete on us */ /* spool_buffer is shared udp buffer, not deleted here */ @@ -2167,7 +2173,8 @@ void tcp_req_info_clear(struct tcp_req_i open = req->open_req_list; while(open) { nopen = open->next; - mesh_state_remove_reply(open->mesh, open->mesh_state, req->cp); + mesh_state_remove_reply(open->mesh, open->mesh_state, req->cp, + NULL, NULL); free(open); open = nopen; } @@ -2189,6 +2196,9 @@ void tcp_req_info_clear(struct tcp_req_i req->done_req_list = NULL; req->num_done_req = 0; req->read_is_closed = 0; + + if(comm_timer_is_set(req->read_again_timer)) + comm_timer_disable(req->read_again_timer); } void @@ -2300,21 +2310,8 @@ int tcp_req_info_handle_read_close(struct tcp_req_info* req) { verbose(VERB_ALGO, "tcp channel read side closed %d", req->cp->fd); - /* reset byte count for (potential) partial read */ - req->cp->tcp_byte_count = 0; - /* if we still have results to write, pick up next and write it */ - if(req->num_done_req != 0) { - tcp_req_pickup_next_result(req); - tcp_req_info_setup_listen(req); - return 1; - } - /* if nothing to do, this closes the connection */ - if(req->num_open_req == 0 && req->num_done_req == 0) - return 0; - /* otherwise, we must be waiting for dns resolve, wait with timeout */ - req->read_is_closed = 1; - tcp_req_info_setup_listen(req); - return 1; + /* RFC 7766 6.2.4 says to drop pending replies when client closes. */ + return 0; /* drop connection */ } void @@ -2884,6 +2881,7 @@ submit_http_error: sldns_buffer_flip(h2_stream->qbuffer); h2_session->postpone_drop = 1; query_read_done = http2_query_read_done(h2_session, h2_stream); + h2_session->postpone_drop = 0; if(query_read_done < 0) return NGHTTP2_ERR_CALLBACK_FAILURE; else if(!query_read_done) { @@ -2893,11 +2891,9 @@ submit_http_error: * failure will result in reclaiming (and closing) * of comm point. */ verbose(VERB_QUERY, "http2 query dropped in worker cb"); - h2_session->postpone_drop = 0; return NGHTTP2_ERR_CALLBACK_FAILURE; } /* nothing to submit right now, query added to mesh. */ - h2_session->postpone_drop = 0; return 0; } if(!http2_submit_dns_response(h2_session)) { @@ -3275,14 +3271,18 @@ nghttp2_session_callbacks* http2_req_cal struct doq_table* doq_table_create(struct config_file* cfg, struct ub_randstate* rnd) { - struct doq_table* table = calloc(1, sizeof(*table)); + struct doq_table* table; + + if (!cfg->quic_port) + return NULL; + table = calloc(1, sizeof(*table)); if(!table) return NULL; #ifdef USE_NGTCP2_CRYPTO_OSSL /* Initialize the ossl crypto, it is harmless to call twice, * and this is before use of doq connections. */ if(ngtcp2_crypto_ossl_init() != 0) { - log_err("ngtcp2_crypto_oss_init failed"); + log_err("ngtcp2_crypto_ossl_init failed"); free(table); return NULL; } @@ -3354,7 +3354,7 @@ conn_tree_del(rbnode_type* node, void* a { struct doq_table* table = (struct doq_table*)arg; struct doq_conn* conn; - if(!node) + if(!node || !table) return; conn = (struct doq_conn*)node->key; if(conn->timer.timer_in_list) { @@ -3409,13 +3409,13 @@ doq_table_delete(struct doq_table* table } struct doq_timer* -doq_timer_find_time(struct doq_table* table, struct timeval* tv) +doq_timer_find_time(struct doq_table* table, ngtcp2_tstamp ts) { struct doq_timer key; struct rbnode_type* node; + log_assert(table != NULL); memset(&key, 0, sizeof(key)); - key.time.tv_sec = tv->tv_sec; - key.time.tv_usec = tv->tv_usec; + key.time_mono = ts; node = rbtree_search(table->timer_tree, &key); if(node) return (struct doq_timer*)node->key; @@ -3463,7 +3463,7 @@ doq_timer_list_remove(struct doq_table* if(!timer->timer_in_list) return; /* The item in the rbtree has the list start and end. */ - rb_timer = doq_timer_find_time(table, &timer->time); + rb_timer = doq_timer_find_time(table, timer->time_mono); if(rb_timer) { if(timer->setlist_prev) timer->setlist_prev->setlist_next = timer->setlist_next; @@ -3509,7 +3509,8 @@ doq_timer_unset(struct doq_table* table, } void doq_timer_set(struct doq_table* table, struct doq_timer* timer, - struct doq_server_socket* worker_doq_socket, struct timeval* tv) + struct doq_server_socket* worker_doq_socket, struct timeval* tv, + ngtcp2_tstamp ts) { struct doq_timer* rb_timer; if(verbosity >= VERB_ALGO && timer->conn) { @@ -3523,14 +3524,14 @@ void doq_timer_set(struct doq_table* tab (int)rel.tv_sec, (int)rel.tv_usec); } if(timer->timer_in_tree || timer->timer_in_list) { - if(timer->time.tv_sec == tv->tv_sec && - timer->time.tv_usec == tv->tv_usec) + if(timer->time_mono == ts) return; /* already set on that time */ doq_timer_unset(table, timer); } - timer->time.tv_sec = tv->tv_sec; - timer->time.tv_usec = tv->tv_usec; - rb_timer = doq_timer_find_time(table, tv); + timer->time_real.tv_sec = tv->tv_sec; + timer->time_real.tv_usec = tv->tv_usec; + timer->time_mono = ts; + rb_timer = doq_timer_find_time(table, ts); if(rb_timer) { /* There is a timeout already with this value. Timer is * added to the setlist. */ @@ -3606,15 +3607,29 @@ doq_conn_create(struct comm_point* c, st return conn; } +/** The arguments for doq stream tree del. */ +struct doq_stream_tree_del_args { + /** The doq table. */ + struct doq_table* table; + /** The doq connection for the stream. */ + struct doq_conn* conn; +}; + /** delete stream tree node */ static void stream_tree_del(rbnode_type* node, void* arg) { - struct doq_table* table = (struct doq_table*)arg; + struct doq_stream_tree_del_args* args = (struct doq_stream_tree_del_args*)arg; + struct doq_table* table = args->table; struct doq_stream* stream; if(!node) return; stream = (struct doq_stream*)node; + if(stream->mesh_state) { + mesh_state_remove_reply(stream->mesh, stream->mesh_state, + args->conn->doq_socket->cp, NULL, stream); + stream->mesh_state = NULL; + } if(stream->in) doq_table_quic_size_subtract(table, stream->inlen); if(stream->out) @@ -3634,9 +3649,14 @@ doq_conn_delete(struct doq_conn* conn, s lock_rw_unlock(&conn->table->conid_lock); /* Remove the app data from ngtcp2 before SSL_free of conn->ssl, * because the ngtcp2 conn is deleted. */ - SSL_set_app_data(conn->ssl, NULL); + if(conn->ssl) + SSL_set_app_data(conn->ssl, NULL); if(conn->stream_tree.count != 0) { - traverse_postorder(&conn->stream_tree, stream_tree_del, table); + struct doq_stream_tree_del_args args; + memset(&args, 0, sizeof(args)); + args.table = table; + args.conn = conn; + traverse_postorder(&conn->stream_tree, stream_tree_del, &args); } free(conn->key.dcid); SSL_free(conn->ssl); @@ -3709,13 +3729,9 @@ int doq_timer_cmp(const void* key1, cons { struct doq_timer* e = (struct doq_timer*)key1; struct doq_timer* f = (struct doq_timer*)key2; - if(e->time.tv_sec < f->time.tv_sec) - return -1; - if(e->time.tv_sec > f->time.tv_sec) - return 1; - if(e->time.tv_usec < f->time.tv_usec) + if(e->time_mono < f->time_mono) return -1; - if(e->time.tv_usec > f->time.tv_usec) + if(e->time_mono > f->time_mono) return 1; return 0; } @@ -3776,7 +3792,7 @@ doq_repinfo_retrieve_localaddr(struct co memset(sa6, 0, *localaddrlen); sa6->sin6_family = AF_INET6; memmove(&sa6->sin6_addr, &repinfo->pktinfo.v6info.ipi6_addr, - *localaddrlen); + sizeof(struct in6_addr)); sa6->sin6_port = repinfo->doq_srcport; #endif } else { @@ -3786,7 +3802,7 @@ doq_repinfo_retrieve_localaddr(struct co memset(sa, 0, *localaddrlen); sa->sin_family = AF_INET; memmove(&sa->sin_addr, &repinfo->pktinfo.v4info.ipi_addr, - *localaddrlen); + sizeof(struct in_addr)); sa->sin_port = repinfo->doq_srcport; #elif defined(IP_RECVDSTADDR) struct sockaddr_in* sa = (struct sockaddr_in*)localaddr; @@ -3949,6 +3965,11 @@ doq_stream_close(struct doq_conn* conn, if(stream->is_closed) return 1; stream->is_closed = 1; + if(stream->mesh_state) { + mesh_state_remove_reply(stream->mesh, stream->mesh_state, + conn->doq_socket->cp, NULL, stream); + stream->mesh_state = NULL; + } doq_stream_off_write_list(conn, stream); if(send_shutdown) { verbose(VERB_ALGO, "doq: shutdown stream_id %d with app_error_code %d", @@ -3978,7 +3999,8 @@ doq_stream_close(struct doq_conn* conn, /** doq stream pick up answer data from buffer */ static int -doq_stream_pickup_answer(struct doq_stream* stream, struct sldns_buffer* buf) +doq_stream_pickup_answer(struct doq_conn* conn, struct doq_stream* stream, + struct sldns_buffer* buf) { stream->is_answer_available = 1; if(stream->out) { @@ -3988,6 +4010,11 @@ doq_stream_pickup_answer(struct doq_stre } stream->nwrite = 0; stream->outlen = sldns_buffer_limit(buf); + if(!doq_table_quic_size_available(conn->doq_socket->table, + conn->doq_socket->cfg, stream->outlen)) { + verbose(VERB_ALGO, "doq stream: no space for reply length"); + return 0; + } /* For quic the output bytes have to stay allocated and available, * for potential resends, until the remote end has acknowledged them. * This includes the tcplen start uint16_t, in outlen_wire. */ @@ -4014,24 +4041,56 @@ doq_stream_send_reply(struct doq_conn* c if(stream->out) doq_table_quic_size_subtract(conn->doq_socket->table, stream->outlen); - if(!doq_stream_pickup_answer(stream, buf)) + if(!doq_stream_pickup_answer(conn, stream, buf)) return 0; doq_table_quic_size_add(conn->doq_socket->table, stream->outlen); doq_stream_on_write_list(conn, stream); doq_conn_write_enable(conn); return 1; } +#endif /* HAVE_NGTCP2 */ + +void +doq_stream_add_meshstate(struct doq_stream* stream, + struct mesh_area* mesh, struct mesh_state* m) +{ +#ifdef HAVE_NGTCP2 + stream->mesh = mesh; + stream->mesh_state = m; +#else + (void)stream; (void)mesh; (void)m; +#endif +} + +void +doq_stream_remove_mesh_state(struct doq_stream* stream) +{ +#ifdef HAVE_NGTCP2 + if(!stream) + return; + stream->mesh_state = NULL; +#else + (void)stream; +#endif +} +#ifdef HAVE_NGTCP2 /** doq stream data length has completed, allocations can be done. False on * allocation failure. */ static int -doq_stream_datalen_complete(struct doq_stream* stream, struct doq_table* table) +doq_stream_datalen_complete(struct doq_conn* conn, struct doq_stream* stream, + struct doq_table* table) { if(stream->inlen > 1024*1024) { log_err("doq stream in length too large %d", (int)stream->inlen); return 0; } + if(!doq_table_quic_size_available(table, conn->doq_socket->cfg, + stream->inlen)) { + verbose(VERB_ALGO, "doq stream: no space for query length"); + return 0; + } stream->in = calloc(1, stream->inlen); if(!stream->in) { log_err("doq could not read stream, calloc failed: " @@ -4076,6 +4135,7 @@ doq_stream_data_complete(struct doq_conn return 0; } c->repinfo.doq_streamid = stream->stream_id; + c->repinfo.doq_stream = stream; conn->doq_socket->current_conn = conn; fptr_ok(fptr_whitelist_comm_point(c->callback)); if( (*c->callback)(c, c->cb_arg, NETEVENT_NOERROR, &c->repinfo)) { @@ -4092,8 +4152,9 @@ doq_stream_data_complete(struct doq_conn /** doq receive data for a stream, more bytes of the incoming data */ static int -doq_stream_recv_data(struct doq_stream* stream, const uint8_t* data, - size_t datalen, int* recv_done, struct doq_table* table) +doq_stream_recv_data(struct doq_conn* conn, struct doq_stream* stream, + const uint8_t* data, size_t datalen, int* recv_done, + struct doq_table* table) { int got_data = 0; /* read the tcplength uint16_t at the start */ @@ -4114,7 +4175,7 @@ doq_stream_recv_data(struct doq_stream* if(stream->nread == 2) { /* the initial length value is completed */ stream->inlen = ntohs(tcplen); - if(!doq_stream_datalen_complete(stream, table)) + if(!doq_stream_datalen_complete(conn, stream, table)) return 0; } else { /* store for later */ @@ -4263,12 +4324,11 @@ doq_submit_new_token(struct doq_conn* co ngtcp2_ssize tokenlen; int ret; const ngtcp2_path* path = ngtcp2_conn_get_path(conn->conn); - ngtcp2_tstamp ts = doq_get_timestamp_nanosec(); tokenlen = ngtcp2_crypto_generate_regular_token(token, conn->doq_socket->static_secret, conn->doq_socket->static_secret_len, path->remote.addr, - path->remote.addrlen, ts); + path->remote.addrlen, doq_get_timestamp_nanosec()); if(tokenlen < 0) { log_err("doq ngtcp2_crypto_generate_regular_token failed"); return 1; @@ -4331,8 +4391,7 @@ doq_stream_open_cb(ngtcp2_conn* ATTR_UNU verbose(VERB_ALGO, "doq: stream with this id already exists"); return 0; } - if(stream_id != 0 && stream_id != 4 && /* allow one stream on a new connection */ - !doq_table_quic_size_available(doq_conn->doq_socket->table, + if(!doq_table_quic_size_available(doq_conn->doq_socket->table, doq_conn->doq_socket->cfg, sizeof(*stream) + 100 /* estimated query in */ + 512 /* estimated response out */ @@ -4390,8 +4449,8 @@ doq_recv_stream_data_cb(ngtcp2_conn* ATT return 0; } if(datalen != 0) { - if(!doq_stream_recv_data(stream, data, datalen, &recv_done, - doq_conn->doq_socket->table)) + if(!doq_stream_recv_data(doq_conn, stream, data, datalen, + &recv_done, doq_conn->doq_socket->table)) return NGTCP2_ERR_CALLBACK_FAILURE; } if((flags&NGTCP2_STREAM_DATA_FLAG_FIN)!=0) { @@ -4455,11 +4514,34 @@ doq_stream_reset_cb(ngtcp2_conn* ATTR_UN "unknown stream %d", (int)stream_id); return 0; } - if(!doq_stream_close(doq_conn, stream, 0)) + if(!doq_stream_close(doq_conn, stream, 1)) return NGTCP2_ERR_CALLBACK_FAILURE; return 0; } +/** ngtcp2 extend_max_stream_data function */ +int doq_extend_max_stream_data_cb(ngtcp2_conn* ATTR_UNUSED(conn), + int64_t stream_id, uint64_t max_data, void* user_data, + void* ATTR_UNUSED(stream_user_data)) +{ + struct doq_conn* doq_conn = (struct doq_conn*)user_data; + struct doq_stream* stream; + verbose(VERB_ALGO, "doq extend_max_stream_data stream id %d " + "max_data %d ", (int)stream_id, (int)max_data); + if(max_data == 0) + return 0; + stream = doq_stream_find(doq_conn, stream_id); + if(!stream) { + verbose(VERB_ALGO, "doq: unknown stream %d", (int)stream_id); + return 0; + } + if(!stream->is_answer_available) + return 0; + doq_stream_on_write_list(doq_conn, stream); + doq_conn_write_enable(doq_conn); + return 0; +} + /** ngtcp2 acked_stream_data_offset callback function */ static int doq_acked_stream_data_offset_cb(ngtcp2_conn* ATTR_UNUSED(conn), @@ -4780,7 +4862,7 @@ doq_ssl_server_setup(SSL_CTX* ctx, struc SSL_set_app_data(ssl, conn); #endif SSL_set_accept_state(ssl); -#ifdef USE_NGTCP2_CRYPTO_OSSL +#ifdef HAVE_SSL_SET_QUIC_TLS_EARLY_DATA_ENABLED SSL_set_quic_tls_early_data_enabled(ssl, 1); #else SSL_set_quic_early_data_enabled(ssl, 1); @@ -4834,6 +4916,7 @@ doq_conn_setup(struct doq_conn* conn, ui callbacks.stream_open = doq_stream_open_cb; callbacks.stream_close = doq_stream_close_cb; callbacks.stream_reset = doq_stream_reset_cb; + callbacks.extend_max_stream_data = doq_extend_max_stream_data_cb; callbacks.acked_stream_data_offset = doq_acked_stream_data_offset_cb; callbacks.recv_stream_data = doq_recv_stream_data_cb; @@ -4888,6 +4971,7 @@ doq_conn_setup(struct doq_conn* conn, ui rv = ngtcp2_conn_server_new(&conn->conn, &scid_cid, &sv_scid, &path, conn->version, &callbacks, &settings, ¶ms, NULL, conn); if(rv != 0) { + conn->conn = NULL; lock_rw_unlock(&conn->table->conid_lock); log_err("ngtcp2_conn_server_new failed: %s", ngtcp2_strerror(rv)); @@ -4922,6 +5006,7 @@ doq_conid_find(struct doq_table* table, key.node.key = &key; key.cid = (void*)data; key.cidlen = datalen; + log_assert(table != NULL); node = rbtree_search(table->conid_tree, &key); if(node) return (struct doq_conid*)node->key; @@ -5109,23 +5194,30 @@ doq_conn_clear_conids(struct doq_conn* c ngtcp2_tstamp doq_get_timestamp_nanosec(void) { -#ifdef CLOCK_REALTIME struct timespec tp; memset(&tp, 0, sizeof(tp)); - /* Get a nanosecond time, that can be compared with the event base. */ - if(clock_gettime(CLOCK_REALTIME, &tp) == -1) { - log_err("clock_gettime failed: %s", strerror(errno)); +#ifdef CLOCK_BOOTTIME + if(clock_gettime(CLOCK_BOOTTIME, &tp) == -1) { +#endif + if(clock_gettime(CLOCK_MONOTONIC, &tp) == -1) { + log_err("clock_gettime failed: %s", strerror(errno)); + } +#ifdef CLOCK_BOOTTIME } +#endif return ((uint64_t)tp.tv_sec)*((uint64_t)1000000000) + ((uint64_t)tp.tv_nsec); -#else +} + +static struct timeval doq_get_timevalue(void) +{ struct timeval tv; + memset(&tv, 0, sizeof(tv)); if(gettimeofday(&tv, NULL) < 0) { log_err("gettimeofday failed: %s", strerror(errno)); + memset(&tv, 0, sizeof(tv)); } - return ((uint64_t)tv.tv_sec)*((uint64_t)1000000000) + - ((uint64_t)tv.tv_usec)*((uint64_t)1000); -#endif /* CLOCK_REALTIME */ + return tv; } /** doq start the closing period for the connection. */ @@ -5248,18 +5340,17 @@ doq_conn_recv(struct comm_point* c, stru int* err_drop) { int ret; - ngtcp2_tstamp ts; struct ngtcp2_path path; memset(&path, 0, sizeof(path)); path.remote.addr = (struct sockaddr*)&paddr->addr; path.remote.addrlen = paddr->addrlen; path.local.addr = (struct sockaddr*)&paddr->localaddr; path.local.addrlen = paddr->localaddrlen; - ts = doq_get_timestamp_nanosec(); ret = ngtcp2_conn_read_pkt(conn->conn, &path, pi, sldns_buffer_begin(c->doq_socket->pkt_buf), - sldns_buffer_limit(c->doq_socket->pkt_buf), ts); + sldns_buffer_limit(c->doq_socket->pkt_buf), + doq_get_timestamp_nanosec()); if(ret != 0) { if(err_retry) *err_retry = 0; @@ -5347,7 +5438,6 @@ doq_conn_write_streams(struct comm_point { struct doq_stream* stream = conn->stream_write_first; ngtcp2_path_storage ps; - ngtcp2_tstamp ts = doq_get_timestamp_nanosec(); size_t num_packets = 0, max_packets = 65535; ngtcp2_path_storage_zero(&ps); @@ -5400,7 +5490,8 @@ doq_conn_write_streams(struct comm_point ret = ngtcp2_conn_writev_stream(conn->conn, &ps.path, &pi, sldns_buffer_begin(c->doq_socket->pkt_buf), sldns_buffer_remaining(c->doq_socket->pkt_buf), - &ndatalen, flags, stream_id, datav, datav_count, ts); + &ndatalen, flags, stream_id, datav, datav_count, + doq_get_timestamp_nanosec()); if(ret < 0) { if(ret == NGTCP2_ERR_WRITE_MORE) { verbose(VERB_ALGO, "doq: write more, ndatalen %d", (int)ndatalen); @@ -5415,26 +5506,20 @@ doq_conn_write_streams(struct comm_point continue; } else if(ret == NGTCP2_ERR_STREAM_DATA_BLOCKED) { verbose(VERB_ALGO, "doq: ngtcp2_conn_writev_stream returned NGTCP2_ERR_STREAM_DATA_BLOCKED"); -#ifdef HAVE_NGTCP2_CCERR_DEFAULT - ngtcp2_ccerr_set_application_error( - &conn->ccerr, -1, NULL, 0); -#else - ngtcp2_connection_close_error_set_application_error(&conn->last_error, -1, NULL, 0); -#endif - if(err_drop) - *err_drop = 0; - if(!doq_conn_close_error(c, conn)) { - if(err_drop) - *err_drop = 1; + if(stream) { + doq_stream_off_write_list(conn, stream); + stream = stream->write_next; + continue; + } else { + break; } - return 0; } else if(ret == NGTCP2_ERR_STREAM_SHUT_WR) { verbose(VERB_ALGO, "doq: ngtcp2_conn_writev_stream returned NGTCP2_ERR_STREAM_SHUT_WR"); #ifdef HAVE_NGTCP2_CCERR_DEFAULT ngtcp2_ccerr_set_application_error( - &conn->ccerr, -1, NULL, 0); + &conn->ccerr, DOQ_APP_ERROR_CODE, NULL, 0); #else - ngtcp2_connection_close_error_set_application_error(&conn->last_error, -1, NULL, 0); + ngtcp2_connection_close_error_set_application_error(&conn->last_error, DOQ_APP_ERROR_CODE, NULL, 0); #endif if(err_drop) *err_drop = 0; @@ -5472,7 +5557,8 @@ doq_conn_write_streams(struct comm_point if(ret == 0) { /* congestion limited */ doq_conn_write_disable(conn); - ngtcp2_conn_update_pkt_tx_time(conn->conn, ts); + ngtcp2_conn_update_pkt_tx_time(conn->conn, + doq_get_timestamp_nanosec()); return 1; } sldns_buffer_set_position(c->doq_socket->pkt_buf, ret); @@ -5486,7 +5572,7 @@ doq_conn_write_streams(struct comm_point if(stream) stream = stream->write_next; } - ngtcp2_conn_update_pkt_tx_time(conn->conn, ts); + ngtcp2_conn_update_pkt_tx_time(conn->conn, doq_get_timestamp_nanosec()); return 1; } @@ -5563,32 +5649,35 @@ doq_table_pop_first(struct doq_table* ta } int -doq_conn_check_timer(struct doq_conn* conn, struct timeval* tv) +doq_conn_check_timer(struct doq_conn* conn, struct timeval* tv, ngtcp2_tstamp* ts) { - ngtcp2_tstamp expiry = ngtcp2_conn_get_expiry(conn->conn); - ngtcp2_tstamp now = doq_get_timestamp_nanosec(); + ngtcp2_tstamp doq_expiry = ngtcp2_conn_get_expiry(conn->conn); + ngtcp2_tstamp doq_now = doq_get_timestamp_nanosec(); ngtcp2_tstamp t; + struct timeval now = doq_get_timevalue(); - if(expiry <= now) { + if(doq_expiry <= doq_now || doq_expiry == UINT64_MAX) { + /* UINT64_MAX means there is no next expiry. */ /* The timer has already expired, add with zero timeout. * This should call the callback straight away. Calling it * from the event callbacks is cleaner than calling it here, * because then it is always called with the same locks and * so on. This routine only has the conn.lock. */ - t = now; + t = doq_now; + memcpy(tv, &now, sizeof(*tv)); } else { - t = expiry; + t = doq_expiry; + memset(tv, 0, sizeof(*tv)); + tv->tv_sec = (doq_expiry - doq_now) / NGTCP2_SECONDS; + tv->tv_usec = ((doq_expiry - doq_now) / NGTCP2_MICROSECONDS)%1000000; + timeval_add(tv, &now); } - /* convert to timeval */ - memset(tv, 0, sizeof(*tv)); - tv->tv_sec = t / NGTCP2_SECONDS; - tv->tv_usec = (t / NGTCP2_MICROSECONDS)%1000000; + *ts = t; /* If we already have a timer, is it the right value? */ if(conn->timer.timer_in_tree || conn->timer.timer_in_list) { - if(conn->timer.time.tv_sec == tv->tv_sec && - conn->timer.time.tv_usec == tv->tv_usec) + if(conn->timer.time_mono == *ts) return 0; } return 1; @@ -5609,13 +5698,12 @@ doq_conn_log_line(struct doq_conn* conn, int doq_conn_handle_timeout(struct doq_conn* conn) { - ngtcp2_tstamp now = doq_get_timestamp_nanosec(); int rv; if(verbosity >= VERB_ALGO) doq_conn_log_line(conn, "timeout"); - rv = ngtcp2_conn_handle_expiry(conn->conn, now); + rv = ngtcp2_conn_handle_expiry(conn->conn, doq_get_timestamp_nanosec()); if(rv != 0) { verbose(VERB_ALGO, "ngtcp2_conn_handle_expiry failed: %s", ngtcp2_strerror(rv)); @@ -5662,6 +5750,8 @@ doq_table_quic_size_available(struct doq struct config_file* cfg, size_t mem) { size_t cur; + if (!table) + return 0; lock_basic_lock(&table->size_lock); cur = table->current_size; lock_basic_unlock(&table->size_lock); Index: sbin/unwind/libunbound/services/listen_dnsport.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/services/listen_dnsport.h,v diff -u -p -r1.14 listen_dnsport.h --- sbin/unwind/libunbound/services/listen_dnsport.h 29 Sep 2025 14:53:38 -0000 1.14 +++ sbin/unwind/libunbound/services/listen_dnsport.h 21 Sep 2026 16:28:24 -0000 @@ -61,6 +61,8 @@ struct config_file; struct addrinfo; struct sldns_buffer; struct tcl_list; +struct mesh_area; +struct mesh_state; /** * Listening for queries structure. @@ -345,6 +347,10 @@ struct tcp_req_info { int num_done_req; /** list of pending writable result packets, malloced one at a time */ struct tcp_req_done_item* done_req_list; + /** the read again timer, when the number of pipelined TCP queries + * is large, it waits, zero time, for a new event loop to service + * the remainder of the TCP traffic on the fd. */ + struct comm_timer* read_again_timer; }; /** @@ -375,10 +381,12 @@ struct tcp_req_done_item { * Create tcp request info structure that keeps track of open * requests on the TCP channel that are resolved at the same time, * and the pending results that have to get written back to that client. + * @param base: comm base for read again timer. * @param spoolbuf: shared buffer * @return new structure or NULL on alloc failure. */ -struct tcp_req_info* tcp_req_info_create(struct sldns_buffer* spoolbuf); +struct tcp_req_info* tcp_req_info_create(struct comm_base* base, + struct sldns_buffer* spoolbuf); /** * Delete tcp request structure. Called by owning commpoint. @@ -538,8 +546,11 @@ void doq_table_delete(struct doq_table* struct doq_timer { /** The rbnode in the tree sorted by timeout value. Key this struct. */ struct rbnode_type node; + /** The timeout value. Monotonic value used with ngtcp2. + * This time value is used for the tree operations. */ + ngtcp2_tstamp time_mono; /** The timeout value. Absolute time value. */ - struct timeval time; + struct timeval time_real; /** If the timer is in the time tree, with the node. */ int timer_in_tree; /** If there are more timers with the exact same timeout value, @@ -689,6 +700,11 @@ struct doq_stream { uint8_t* out; /** if the stream is on the write list */ uint8_t on_write_list; + /** The mesh area and mesh state, set when this stream's query was + * dispatched into the mesh; used to detach the reply on stream close */ + struct mesh_area* mesh; + /** the mesh state for the query, is nonNULL when there is one. */ + struct mesh_state* mesh_state; /** the prev and next on the write list, if on the list */ struct doq_stream* write_prev, *write_next; }; @@ -791,7 +807,16 @@ int doq_stream_close(struct doq_conn* co /** send reply for a connection */ int doq_stream_send_reply(struct doq_conn* conn, struct doq_stream* stream, struct sldns_buffer* buf); +#endif /* HAVE_NGTCP2 */ +/** add mesh state to doq stream */ +void doq_stream_add_meshstate(struct doq_stream* stream, + struct mesh_area* mesh, struct mesh_state* m); + +/** remove mesh state from doq stream */ +void doq_stream_remove_mesh_state(struct doq_stream* stream); + +#ifdef HAVE_NGTCP2 /** the connection has write interest, wants to write packets */ void doq_conn_write_enable(struct doq_conn* conn); @@ -813,10 +838,12 @@ struct doq_conn* doq_table_pop_first(str * doq check if the timer for the conn needs to be changed. * @param conn: connection, caller must hold lock on it. * @param tv: time value, absolute time, returned. + * @param ts: time stamp, absolute time, returned. * @return true if timer needs to be set to tv, false if no change is needed * to the timer. The timer is already set to the right time in that case. */ -int doq_conn_check_timer(struct doq_conn* conn, struct timeval* tv); +int doq_conn_check_timer(struct doq_conn* conn, struct timeval* tv, + ngtcp2_tstamp* ts); /** doq remove timer from tree */ void doq_timer_tree_remove(struct doq_table* table, struct doq_timer* timer); @@ -829,11 +856,12 @@ void doq_timer_unset(struct doq_table* t /** doq set the timer and add it. */ void doq_timer_set(struct doq_table* table, struct doq_timer* timer, - struct doq_server_socket* worker_doq_socket, struct timeval* tv); + struct doq_server_socket* worker_doq_socket, struct timeval* tv, + ngtcp2_tstamp ts); /** doq find a timeout in the timer tree */ struct doq_timer* doq_timer_find_time(struct doq_table* table, - struct timeval* tv); + ngtcp2_tstamp ts); /** doq handle timeout for a connection. Pass conn locked. Returns false for * deletion. */ @@ -851,6 +879,9 @@ int doq_table_quic_size_available(struct /** doq get the quic size value */ size_t doq_table_quic_size_get(struct doq_table* table); + +/** get a timestamp in nanoseconds */ +ngtcp2_tstamp doq_get_timestamp_nanosec(void); #endif /* HAVE_NGTCP2 */ char* set_ip_dscp(int socket, int addrfamily, int ds); @@ -866,8 +897,4 @@ void doq_client_event_cb(int fd, short e /** timer event callback for testcode/doqclient */ void doq_client_timer_cb(int fd, short event, void* arg); -#ifdef HAVE_NGTCP2 -/** get a timestamp in nanoseconds */ -ngtcp2_tstamp doq_get_timestamp_nanosec(void); -#endif #endif /* LISTEN_DNSPORT_H */ Index: sbin/unwind/libunbound/services/localzone.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/services/localzone.c,v diff -u -p -r1.16 localzone.c --- sbin/unwind/libunbound/services/localzone.c 14 Sep 2025 15:16:53 -0000 1.16 +++ sbin/unwind/libunbound/services/localzone.c 21 Sep 2026 16:28:24 -0000 @@ -56,6 +56,24 @@ * with 16 bytes for an A record, a 64K packet has about 4000 max */ #define LOCALZONE_RRSET_COUNT_MAX 4096 +static const char* default_zones_reverse_array[] = { + "127.in-addr.arpa.", /* reverse ip4 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.", /* reverse ip6 zone */ + 0 +}; +const char** local_zones_default_reverse = default_zones_reverse_array; + +static const char* default_zones_special_array[] = { + "test.", /* RFC 6761 */ + "invalid.", /* RFC 6761 */ + "onion.", /* RFC 7686 */ + "home.arpa.", /* RFC 8375 */ + "resolver.arpa.", /* RFC 9462 */ + "service.arpa.", /* RFC 9665 */ + 0 +}; +const char** local_zones_default_special = default_zones_special_array; + /** print all RRsets in local zone */ static void local_zone_out(struct local_zone* z) @@ -368,8 +386,6 @@ new_local_rrset(struct regional* region, log_err("out of memory"); return NULL; } - rrset->next = node->rrsets; - node->rrsets = rrset; rrset->rrset = (struct ub_packed_rrset_key*) regional_alloc_zero(region, sizeof(*rrset->rrset)); if(!rrset->rrset) { @@ -390,6 +406,8 @@ new_local_rrset(struct regional* region, rrset->rrset->rk.dname_len = node->namelen; rrset->rrset->rk.type = htons(rrtype); rrset->rrset->rk.rrset_class = htons(rrclass); + rrset->next = node->rrsets; + node->rrsets = rrset; return rrset; } @@ -413,6 +431,10 @@ rrset_insert_rr(struct regional* region, pd->rr_ttl = regional_alloc(region, sizeof(*pd->rr_ttl)*pd->count); pd->rr_data = regional_alloc(region, sizeof(*pd->rr_data)*pd->count); if(!pd->rr_len || !pd->rr_ttl || !pd->rr_data) { + pd->count--; + pd->rr_len = oldlen; + pd->rr_ttl = oldttl; + pd->rr_data = olddata; log_err("out of memory"); return 0; } @@ -428,6 +450,10 @@ rrset_insert_rr(struct regional* region, pd->rr_ttl[0] = ttl; pd->rr_data[0] = regional_alloc_init(region, rdata, rdata_len); if(!pd->rr_data[0]) { + pd->count--; + pd->rr_len = oldlen; + pd->rr_ttl = oldttl; + pd->rr_data = olddata; log_err("out of memory"); return 0; } @@ -650,10 +676,12 @@ lz_enter_rr_str(struct local_zones* zone } labs = dname_count_size_labels(rr_name, &len); lock_rw_rdlock(&zones->lock); - z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type); + z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type, 1); if(!z) { lock_rw_unlock(&zones->lock); - fatal_exit("internal error: no zone for rr %s", rr); + log_err("internal error: no zone for rr %s", rr); + free(rr_name); + return 0; } lock_rw_wrlock(&z->lock); lock_rw_unlock(&zones->lock); @@ -834,7 +862,7 @@ lz_nodefault(struct config_file* cfg, co for(p = cfg->local_zones_nodefault; p; p = p->next) { /* compare zone name, lowercase, compare without ending . */ - if(strncasecmp(p->str, name, len) == 0 && + if(strncasecmp(p->str, name, len) == 0 && (strlen(p->str) == len || (strlen(p->str)==len+1 && p->str[len] == '.'))) return 1; @@ -842,6 +870,45 @@ lz_nodefault(struct config_file* cfg, co return 0; } +/** enter reverse default zone */ +static int +add_reverse_default(struct local_zones* zones, struct config_file* cfg, + const char* name) +{ + struct local_zone* z; + char str[1024]; /* known long enough */ + if(lz_exists(zones, name) || lz_nodefault(cfg, name)) + return 1; /* do not enter default content */ + if(!(z=lz_enter_zone(zones, name, "static", LDNS_RR_CLASS_IN))) + return 0; + snprintf(str, sizeof(str), "%s 10800 IN SOA localhost. " + "nobody.invalid. 1 3600 1200 604800 10800", name); + if(!lz_enter_rr_into_zone(z, str)) { + lock_rw_unlock(&z->lock); + return 0; + } + snprintf(str, sizeof(str), "%s 10800 IN NS localhost. ", name); + if(!lz_enter_rr_into_zone(z, str)) { + lock_rw_unlock(&z->lock); + return 0; + } + if(strncasecmp("127.in-addr.arpa.", name, 17) == 0) { + if(!lz_enter_rr_into_zone(z, + "1.0.0.127.in-addr.arpa. 10800 IN PTR localhost.")) { + lock_rw_unlock(&z->lock); + return 0; + } + } else if(strncasecmp("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.", name, 73) == 0) { + snprintf(str, sizeof(str), "%s 10800 IN PTR localhost.", name); + if(!lz_enter_rr_into_zone(z, str)) { + lock_rw_unlock(&z->lock); + return 0; + } + } + lock_rw_unlock(&z->lock); + return 1; +} + /** enter (AS112) empty default zone */ static int add_empty_default(struct local_zones* zones, struct config_file* cfg, @@ -902,72 +969,23 @@ int local_zone_enter_defaults(struct loc } lock_rw_unlock(&z->lock); } - /* reverse ip4 zone */ - if(!lz_exists(zones, "127.in-addr.arpa.") && - !lz_nodefault(cfg, "127.in-addr.arpa.")) { - if(!(z=lz_enter_zone(zones, "127.in-addr.arpa.", "static", - LDNS_RR_CLASS_IN)) || - !lz_enter_rr_into_zone(z, - "127.in-addr.arpa. 10800 IN NS localhost.") || - !lz_enter_rr_into_zone(z, - "127.in-addr.arpa. 10800 IN SOA localhost. " - "nobody.invalid. 1 3600 1200 604800 10800") || - !lz_enter_rr_into_zone(z, - "1.0.0.127.in-addr.arpa. 10800 IN PTR localhost.")) { + + /* ip4 and ip6 reverse */ + for(zstr = local_zones_default_reverse; *zstr; zstr++) { + if(!add_reverse_default(zones, cfg, *zstr)) { log_err("out of memory adding default zone"); - if(z) { lock_rw_unlock(&z->lock); } return 0; } - lock_rw_unlock(&z->lock); } - /* reverse ip6 zone */ - if(!lz_exists(zones, "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.") && - !lz_nodefault(cfg, "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.")) { - if(!(z=lz_enter_zone(zones, "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.", "static", - LDNS_RR_CLASS_IN)) || - !lz_enter_rr_into_zone(z, - "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. 10800 IN NS localhost.") || - !lz_enter_rr_into_zone(z, - "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. 10800 IN SOA localhost. " - "nobody.invalid. 1 3600 1200 604800 10800") || - !lz_enter_rr_into_zone(z, - "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. 10800 IN PTR localhost.")) { + + /* special-use zones */ + for(zstr = local_zones_default_special; *zstr; zstr++) { + if(!add_empty_default(zones, cfg, *zstr)) { log_err("out of memory adding default zone"); - if(z) { lock_rw_unlock(&z->lock); } return 0; } - lock_rw_unlock(&z->lock); - } - /* home.arpa. zone (RFC 8375) */ - if(!add_empty_default(zones, cfg, "home.arpa.")) { - 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"); - return 0; - } - /* test. zone (RFC 6761) */ - if(!add_empty_default(zones, cfg, "test.")) { - log_err("out of memory adding default zone"); - return 0; - } - /* invalid. zone (RFC 6761) */ - if(!add_empty_default(zones, cfg, "invalid.")) { - log_err("out of memory adding default zone"); - return 0; } + /* block AS112 zones, unless asked not to */ if(!cfg->unblock_lan_zones) { for(zstr = as112_zones; *zstr; zstr++) { @@ -998,23 +1016,23 @@ static struct local_zone* find_closest_p struct local_zone* prev) { struct local_zone* p; - int m; + int m; if(!prev || prev->dclass != curr->dclass) return NULL; (void)dname_lab_cmp(prev->name, prev->namelabs, curr->name, curr->namelabs, &m); /* we know prev is smaller */ - /* sort order like: . com. bla.com. zwb.com. net. */ - /* find the previous, or parent-parent-parent */ + /* sort order like: . com. bla.com. zwb.com. net. */ + /* find the previous, or parent-parent-parent */ for(p = prev; p; p = p->parent) { - /* looking for name with few labels, a parent */ - if(p->namelabs <= m) { - /* ==: since prev matched m, this is closest*/ - /* <: prev matches more, but is not a parent, - * this one is a (grand)parent */ + /* looking for name with few labels, a parent */ + if(p->namelabs <= m) { + /* ==: since prev matched m, this is closest*/ + /* <: prev matches more, but is not a parent, + * this one is a (grand)parent */ return p; } } return NULL; - } +} /** setup parent pointers, so that a lookup can be done for closest match */ void @@ -1029,7 +1047,7 @@ lz_init_parents(struct local_zones* zone if(node->override_tree) addr_tree_init_parents(node->override_tree); lock_rw_unlock(&node->lock); - } + } lock_rw_unlock(&zones->lock); } @@ -1062,14 +1080,15 @@ lz_setup_implicit(struct local_zones* zo labs = dname_count_size_labels(rr_name, &len); lock_rw_rdlock(&zones->lock); if(!local_zones_lookup(zones, rr_name, len, labs, rr_class, - rr_type)) { + rr_type, 1)) { /* Check if there is a zone that this could go * under but for different class; created zones are * always for LDNS_RR_CLASS_IN. Create the zone with * a different class but the same configured * local_zone_type. */ struct local_zone* z = local_zones_lookup(zones, - rr_name, len, labs, LDNS_RR_CLASS_IN, rr_type); + rr_name, len, labs, LDNS_RR_CLASS_IN, rr_type, + 1); if(z) { uint8_t* name = memdup(z->name, z->namelen); size_t znamelen = z->namelen; @@ -1231,28 +1250,48 @@ local_zones_apply_cfg(struct local_zones struct local_zone* local_zones_lookup(struct local_zones* zones, - uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype) + uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype, + int foradd) { return local_zones_tags_lookup(zones, name, len, labs, - dclass, dtype, NULL, 0, 1); + dclass, dtype, NULL, 0, 1, foradd); } struct local_zone* local_zones_tags_lookup(struct local_zones* zones, uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype, - uint8_t* taglist, size_t taglen, int ignoretags) + uint8_t* taglist, size_t taglen, int ignoretags, int foradd) { rbnode_type* res = NULL; struct local_zone *result; struct local_zone key; int m; + key.node.key = &key; + key.dclass = dclass; /* for type DS use a zone higher when on a zonecut */ if(dtype == LDNS_RR_TYPE_DS && !dname_is_root(name)) { - dname_remove_label(&name, &len); - labs--; + /* If this is at a zone cut, of a local-zone, and it is + * of type always_refuse. Then also refuse the type DS + * for it. That could make it DNSSEC bogus, but it is + * REFUSED anyway. It stops CNAME type answers in the + * type DS lookup. */ + key.name = name; + key.namelen = len; + key.namelabs = labs; + /* For additions and removals, use the ordinary rule, + * to remove a label for type DS to locate the parent zone. + * That is where the DS RR needs to be put. */ + if(!foradd && + (result=(struct local_zone*)rbtree_search( + &zones->ztree, &key)) != NULL && + result->type == local_zone_always_refuse) { + /* The type DS does not go up one label. */ + return result; + } else { + dname_remove_label(&name, &len); + labs--; + } } - key.node.key = &key; - key.dclass = dclass; key.name = name; key.namelen = len; key.namelabs = labs; @@ -1471,8 +1510,10 @@ find_tag_datas(struct query_info* qinfo, return 0; /* out of memory */ qinfo->local_alias->rrset = regional_alloc_init(temp, r, sizeof(*r)); - if(!qinfo->local_alias->rrset) + if(!qinfo->local_alias->rrset) { + qinfo->local_alias = NULL; return 0; /* out of memory */ + } } return result; } @@ -1538,13 +1579,17 @@ local_data_answer(struct local_zone* z, return 0; /* out of memory */ qinfo->local_alias->rrset = regional_alloc_init( temp, lr->rrset, sizeof(*lr->rrset)); - if(!qinfo->local_alias->rrset) + if(!qinfo->local_alias->rrset) { + qinfo->local_alias = NULL; return 0; /* out of memory */ + } qinfo->local_alias->rrset->rk.dname = qinfo->qname; qinfo->local_alias->rrset->rk.dname_len = qinfo->qname_len; get_cname_target(lr->rrset, &ctarget, &ctargetlen); - if(!ctargetlen) + if(!ctargetlen) { + qinfo->local_alias = NULL; return 0; /* invalid cname */ + } if(dname_is_wild(ctarget)) { /* synthesize cname target */ struct packed_rrset_data* d, *lr_d; @@ -1573,8 +1618,10 @@ local_data_answer(struct local_zone* z, sizeof(struct packed_rrset_data) + sizeof(size_t) + sizeof(uint8_t*) + sizeof(time_t) + sizeof(uint16_t) + newtargetlen); - if(!d) + if(!d) { + qinfo->local_alias = NULL; return 0; /* out of memory */ + } lr_d = (struct packed_rrset_data*)lr->rrset->entry.data; qinfo->local_alias->rrset->entry.data = d; d->ttl = lr_d->rr_ttl[0]; /* RFC6672-like behavior: @@ -1621,7 +1668,7 @@ local_zone_does_not_cover(struct local_z struct local_data key; struct local_data* ld = NULL; struct local_rrset* lr = NULL; - if(z->type == local_zone_always_transparent || z->type == local_zone_block_a) + if(z->type == local_zone_always_transparent || z->type == local_zone_block_a || z->type == local_zone_block_aaaa) return 1; if(z->type != local_zone_transparent && z->type != local_zone_typetransparent @@ -1632,7 +1679,9 @@ local_zone_does_not_cover(struct local_z key.namelen = qinfo->qname_len; key.namelabs = labs; ld = (struct local_data*)rbtree_search(&z->data, &key.node); - if(z->type == local_zone_transparent || z->type == local_zone_inform) + if(z->type == local_zone_transparent || z->type == local_zone_inform + || z->type == local_zone_block_a_wdata + || z->type == local_zone_block_aaaa_wdata) return (ld == NULL); if(ld) lr = local_data_find_type(ld, qinfo->qtype, 1); @@ -1698,7 +1747,8 @@ local_zones_zone_answer(struct local_zon || lz_type == local_zone_always_transparent) { /* no NODATA or NXDOMAINS for this zone type */ return 0; - } else if(lz_type == local_zone_block_a) { + } else if(lz_type == local_zone_block_a || + lz_type == local_zone_block_a_wdata) { /* Return NODATA for all A queries */ if(qinfo->qtype == LDNS_RR_TYPE_A) { local_error_encode(qinfo, env, edns, repinfo, buf, temp, @@ -1708,6 +1758,17 @@ local_zones_zone_answer(struct local_zon } return 0; + } else if(lz_type == local_zone_block_aaaa || + lz_type == local_zone_block_aaaa_wdata) { + /* Return NODATA for all AAAA queries */ + if(qinfo->qtype == LDNS_RR_TYPE_AAAA) { + local_error_encode(qinfo, env, edns, repinfo, buf, temp, + LDNS_RCODE_NOERROR, (LDNS_RCODE_NOERROR|BIT_AA), + LDNS_EDE_NONE, NULL); + return 1; + } + + return 0; } else if(lz_type == local_zone_always_null) { /* 0.0.0.0 or ::0 or noerror/nodata for this zone type, * used for blocklists. */ @@ -1863,7 +1924,7 @@ local_zones_answer(struct local_zones* z if(view->local_zones && (z = local_zones_lookup(view->local_zones, qinfo->qname, qinfo->qname_len, labs, - qinfo->qclass, qinfo->qtype))) { + qinfo->qclass, qinfo->qtype, 0))) { lock_rw_rdlock(&z->lock); lzt = z->type; } @@ -1875,7 +1936,10 @@ local_zones_answer(struct local_zones* z lzt == local_zone_typetransparent || lzt == local_zone_inform || lzt == local_zone_always_transparent || - lzt == local_zone_block_a) && + lzt == local_zone_block_a || + lzt == local_zone_block_aaaa || + lzt == local_zone_block_a_wdata || + lzt == local_zone_block_aaaa_wdata) && local_zone_does_not_cover(z, qinfo, labs)) { lock_rw_unlock(&z->lock); z = NULL; @@ -1897,7 +1961,7 @@ local_zones_answer(struct local_zones* z lock_rw_rdlock(&zones->lock); if(!(z = local_zones_tags_lookup(zones, qinfo->qname, qinfo->qname_len, labs, qinfo->qclass, qinfo->qtype, - taglist, taglen, 0))) { + taglist, taglen, 0, 0))) { lock_rw_unlock(&zones->lock); return 0; } @@ -1924,6 +1988,7 @@ local_zones_answer(struct local_zones* z if(lzt != local_zone_always_refuse && lzt != local_zone_always_transparent && lzt != local_zone_block_a + && lzt != local_zone_block_aaaa && lzt != local_zone_always_nxdomain && lzt != local_zone_always_nodata && lzt != local_zone_always_deny @@ -1955,6 +2020,9 @@ const char* local_zone_type2str(enum loc case local_zone_inform_redirect: return "inform_redirect"; case local_zone_always_transparent: return "always_transparent"; case local_zone_block_a: return "block_a"; + case local_zone_block_aaaa: return "block_aaaa"; + case local_zone_block_a_wdata: return "block_a_wdata"; + case local_zone_block_aaaa_wdata: return "block_aaaa_wdata"; case local_zone_always_refuse: return "always_refuse"; case local_zone_always_nxdomain: return "always_nxdomain"; case local_zone_always_nodata: return "always_nodata"; @@ -1991,6 +2059,12 @@ int local_zone_str2type(const char* type *t = local_zone_always_transparent; else if(strcmp(type, "block_a") == 0) *t = local_zone_block_a; + else if(strcmp(type, "block_aaaa") == 0) + *t = local_zone_block_aaaa; + else if(strcmp(type, "block_a_wdata") == 0) + *t = local_zone_block_a_wdata; + else if(strcmp(type, "block_aaaa_wdata") == 0) + *t = local_zone_block_aaaa_wdata; else if(strcmp(type, "always_refuse") == 0) *t = local_zone_always_refuse; else if(strcmp(type, "always_nxdomain") == 0) @@ -2102,7 +2176,8 @@ local_zones_add_RR(struct local_zones* z /* could first try readlock then get writelock if zone does not exist, * but we do not add enough RRs (from multiple threads) to optimize */ lock_rw_wrlock(&zones->lock); - z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type); + z = local_zones_lookup(zones, rr_name, len, labs, rr_class, rr_type, + 1); if(!z) { z = local_zones_add_zone(zones, rr_name, len, labs, rr_class, local_zone_transparent); @@ -2180,7 +2255,8 @@ void local_zones_del_data(struct local_z /* remove DS */ lock_rw_rdlock(&zones->lock); - z = local_zones_lookup(zones, name, len, labs, dclass, LDNS_RR_TYPE_DS); + z = local_zones_lookup(zones, name, len, labs, dclass, LDNS_RR_TYPE_DS, + 1); if(z) { lock_rw_wrlock(&z->lock); d = local_zone_find_data(z, name, len, labs); @@ -2194,7 +2270,7 @@ void local_zones_del_data(struct local_z /* remove other types */ lock_rw_rdlock(&zones->lock); - z = local_zones_lookup(zones, name, len, labs, dclass, 0); + z = local_zones_lookup(zones, name, len, labs, dclass, 0, 1); if(!z) { /* no such zone, we're done */ lock_rw_unlock(&zones->lock); Index: sbin/unwind/libunbound/services/localzone.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/services/localzone.h,v diff -u -p -r1.9 localzone.h --- sbin/unwind/libunbound/services/localzone.h 14 Sep 2025 15:16:53 -0000 1.9 +++ sbin/unwind/libunbound/services/localzone.h 21 Sep 2026 16:28:24 -0000 @@ -57,6 +57,9 @@ struct sldns_buffer; struct comm_reply; struct config_strlist; +extern const char** local_zones_default_special; +extern const char** local_zones_default_reverse; + /** * Local zone type * This type determines processing for queries that did not match @@ -90,6 +93,12 @@ enum localzone_type { local_zone_always_transparent, /** resolve normally, even when there is local data but return NODATA for A queries */ local_zone_block_a, + /** resolve normally, even when there is local data, but return NODATA for AAAA queries */ + local_zone_block_aaaa, + /** resolve normally, use local data, else return NODATA for A queries */ + local_zone_block_a_wdata, + /** resolve normally, use local data, else return NODATA for AAAA queries */ + local_zone_block_aaaa_wdata, /** answer with error, even when there is local data */ local_zone_always_refuse, /** answer with nxdomain, even when there is local data */ @@ -262,11 +271,13 @@ void local_zone_delete(struct local_zone * @param taglen: length of taglist. * @param ignoretags: lookup zone by name and class, regardless the * local-zone's tags. + * @param foradd: if the lookup is for addition or removal of the type. + * Used for type DS. The lookup for answers turns this off. * @return closest local_zone or NULL if no covering zone is found. */ struct local_zone* local_zones_tags_lookup(struct local_zones* zones, uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype, - uint8_t* taglist, size_t taglen, int ignoretags); + uint8_t* taglist, size_t taglen, int ignoretags, int foradd); /** * Lookup zone that contains the given name, class. @@ -278,10 +289,13 @@ struct local_zone* local_zones_tags_look * @param dclass: class to lookup. * @param dtype: type of the record, if type DS then a zone higher up is found * pass 0 to just plain find a zone for a name. + * @param foradd: if the lookup is for addition or removal of the type. + * Used for type DS. The lookup for answers turns this off. * @return closest local_zone or NULL if no covering zone is found. */ struct local_zone* local_zones_lookup(struct local_zones* zones, - uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype); + uint8_t* name, size_t len, int labs, uint16_t dclass, uint16_t dtype, + int foradd); /** * Debug helper. Print all zones @@ -565,7 +579,7 @@ enum respip_action { respip_always_nxdomain = local_zone_always_nxdomain, /** answer with nodata response */ respip_always_nodata = local_zone_always_nodata, - /** answer with nodata response */ + /** drop query */ respip_always_deny = local_zone_always_deny, /** RPZ: truncate answer in order to force switch to tcp */ respip_truncate = local_zone_truncate, Index: sbin/unwind/libunbound/services/mesh.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/services/mesh.c,v diff -u -p -r1.23 mesh.c --- sbin/unwind/libunbound/services/mesh.c 29 Sep 2025 14:53:38 -0000 1.23 +++ sbin/unwind/libunbound/services/mesh.c 21 Sep 2026 16:28:24 -0000 @@ -231,6 +231,7 @@ mesh_create(struct module_stack* stack, mesh->ans_expired = 0; mesh->ans_cachedb = 0; mesh->num_queries_discard_timeout = 0; + mesh->num_queries_replyaddr_limit = 0; mesh->num_queries_wait_limit = 0; mesh->num_dns_error_reports = 0; mesh->max_reply_states = env->cfg->num_queries_per_thread; @@ -296,12 +297,14 @@ int mesh_make_new_space(struct mesh_area if(mesh->num_reply_states < mesh->max_reply_states) return 1; /* try to kick out a jostle-list item */ - if(m && m->reply_list && m->list_select == mesh_jostle_list) { + if(m && m->list_select == mesh_jostle_list) { /* how old is it? */ struct timeval age; - timeval_subtract(&age, mesh->env->now_tv, - &m->reply_list->start_time); - if(timeval_smaller(&mesh->jostle_max, &age)) { + if(m->has_first_reply_time) + timeval_subtract(&age, mesh->env->now_tv, + &m->first_reply_time); + if(!m->has_first_reply_time || + timeval_smaller(&mesh->jostle_max, &age)) { /* its a goner */ log_nametypeclass(VERB_ALGO, "query jostled out to " "make space for a new one", @@ -348,7 +351,7 @@ mesh_serve_expired_lookup(struct module_ key = (struct msgreply_entry*)e->key; data = (struct reply_info*)e->data; - if(data->ttl < timenow) *is_expired = 1; + if(TTL_IS_EXPIRED(data->ttl, timenow)) *is_expired = 1; msg = tomsg(qstate->env, &key->key, data, qstate->region, timenow, qstate->env->cfg->serve_expired, qstate->env->scratch); if(!msg) @@ -370,7 +373,7 @@ mesh_serve_expired_lookup(struct module_ "validation"); goto bail_out; /* need to validate cache entry first */ } else if(msg->rep->security == sec_status_secure && - !reply_all_rrsets_secure(msg->rep) && must_validate) { + !reply_an_ns_rrsets_secure(msg->rep) && must_validate) { verbose(VERB_ALGO, "Serve expired: secure entry" " changed status"); goto bail_out; /* rrset changed, re-verify */ @@ -421,6 +424,44 @@ mesh_serve_expired_init(struct mesh_stat return 1; } +/** remove a reply without accounting, rollback the add reply. */ +static void +mesh_remove_reply_without_accounting(struct mesh_state* s, + struct mesh_reply* todel) +{ + struct mesh_reply* r, *prev = NULL; + for(r = s->reply_list; r; r = r->next) { + if(r == todel) { + if(prev) + prev->next = r->next; + else s->reply_list = r->next; + r->next = NULL; + /* todel is allocated in region */ + return; + } + prev = r; + } +} + +/** remove a callback without accounting, rollback the add reply. */ +static void +mesh_remove_callback_without_accounting(struct mesh_state* s, + struct mesh_cb* todel) +{ + struct mesh_cb* r, *prev = NULL; + for(r = s->cb_list; r; r = r->next) { + if(r == todel) { + if(prev) + prev->next = r->next; + else s->cb_list = r->next; + r->next = NULL; + /* todel is allocated in region */ + return; + } + prev = r; + } +} + void mesh_new_client(struct mesh_area* mesh, struct query_info* qinfo, struct respip_client_info* cinfo, uint16_t qflags, struct edns_data* edns, struct comm_reply* rep, uint16_t qid, @@ -430,7 +471,8 @@ void mesh_new_client(struct mesh_area* m int unique = unique_mesh_state(edns->opt_list_in, mesh->env); int was_detached = 0; int was_noreply = 0; - int added = 0; + int added = 0, added_reply_without_accounting = 0, added_tcp = 0; + struct mesh_reply* repadded = NULL; int timeout = mesh->env->cfg->serve_expired? mesh->env->cfg->serve_expired_client_timeout:0; struct sldns_buffer* r_buffer = rep->c->buffer; @@ -441,9 +483,18 @@ void mesh_new_client(struct mesh_area* m if(!infra_wait_limit_allowed(mesh->env->infra_cache, rep, edns->cookie_valid, mesh->env->cfg)) { verbose(VERB_ALGO, "Too many queries waiting from the IP. " - "dropping incoming query."); - comm_point_drop_reply(rep); + "servfail incoming query."); mesh->num_queries_wait_limit++; + edns_opt_list_append_ede(&edns->opt_list_out, + mesh->env->scratch, LDNS_EDE_OTHER, + "Too many queries queued up and waiting from the IP"); + if(!inplace_cb_reply_servfail_call(mesh->env, qinfo, NULL, NULL, + LDNS_RCODE_SERVFAIL, edns, rep, mesh->env->scratch, mesh->env->now_tv)) + edns->opt_list_inplace_cb_out = NULL; + error_encode(r_buffer, LDNS_RCODE_SERVFAIL, + qinfo, qid, qflags, edns); + regional_free_all(mesh->env->scratch); + comm_point_send_reply(rep); return; } if(!unique) @@ -453,6 +504,10 @@ void mesh_new_client(struct mesh_area* m if(!mesh_make_new_space(mesh, rep->c->buffer)) { verbose(VERB_ALGO, "Too many queries. dropping " "incoming query."); + if(rep->c->use_h2) + http2_stream_remove_mesh_state(rep->c->h2_stream); + else if(rep->c->type == comm_doq && rep->doq_stream) + doq_stream_remove_mesh_state(rep->doq_stream); comm_point_drop_reply(rep); mesh->stats_dropped++; return; @@ -464,8 +519,12 @@ void mesh_new_client(struct mesh_area* m if(mesh->num_reply_addrs > mesh->max_reply_states*16) { verbose(VERB_ALGO, "Too many requests queued. " "dropping incoming query."); + if(rep->c->use_h2) + http2_stream_remove_mesh_state(rep->c->h2_stream); + else if(rep->c->type == comm_doq && rep->doq_stream) + doq_stream_remove_mesh_state(rep->doq_stream); comm_point_drop_reply(rep); - mesh->stats_dropped++; + mesh->num_queries_replyaddr_limit++; return; } } @@ -524,18 +583,22 @@ void mesh_new_client(struct mesh_area* m } } /* add reply to s */ - if(!mesh_state_add_reply(s, edns, rep, qid, qflags, qinfo)) { + if(!mesh_state_add_reply(s, edns, rep, qid, qflags, qinfo, &repadded)) { log_err("mesh_new_client: out of memory; SERVFAIL"); goto servfail_mem; } + added_reply_without_accounting = 1; if(rep->c->tcp_req_info) { if(!tcp_req_info_add_meshstate(rep->c->tcp_req_info, mesh, s)) { log_err("mesh_new_client: out of memory add tcpreqinfo"); goto servfail_mem; } } + added_tcp = 1; if(rep->c->use_h2) { http2_stream_add_meshstate(rep->c->h2_stream, mesh, s); + } else if(rep->c->type == comm_doq && rep->doq_stream) { + doq_stream_add_meshstate(rep->doq_stream, mesh, s); } /* add serve expired timer if required and not already there */ if(timeout && !mesh_serve_expired_init(s, timeout)) { @@ -553,6 +616,8 @@ void mesh_new_client(struct mesh_area* m } } #endif + /* Since the acccounting now happens, + * added_reply_without_accounting = 0; but that is not used. */ infra_wait_limit_inc(mesh->env->infra_cache, rep, *mesh->env->now, mesh->env->cfg); /* update statistics */ @@ -589,7 +654,14 @@ servfail_mem: qinfo, qid, qflags, edns); if(rep->c->use_h2) http2_stream_remove_mesh_state(rep->c->h2_stream); + else if(rep->c->type == comm_doq && rep->doq_stream) + doq_stream_remove_mesh_state(rep->doq_stream); comm_point_send_reply(rep); + if(added_reply_without_accounting) { + mesh_remove_reply_without_accounting(s, repadded); + if(added_tcp && rep->c->tcp_req_info) + tcp_req_info_remove_mesh_state(rep->c->tcp_req_info, s); + } if(added) mesh_state_delete(&s->s); return; @@ -598,7 +670,8 @@ servfail_mem: int mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo, uint16_t qflags, struct edns_data* edns, sldns_buffer* buf, - uint16_t qid, mesh_cb_func_type cb, void* cb_arg, int rpz_passthru) + uint16_t qid, mesh_cb_func_type cb, void* cb_arg, int rpz_passthru, + void** unique_info) { struct mesh_state* s = NULL; int unique = unique_mesh_state(edns->opt_list_in, mesh->env); @@ -607,6 +680,7 @@ mesh_new_callback(struct mesh_area* mesh int was_detached = 0; int was_noreply = 0; int added = 0; + struct mesh_cb* add_cb = NULL; uint16_t mesh_flags = qflags&(BIT_RD|BIT_CD); if(!unique) s = mesh_area_find(mesh, NULL, qinfo, mesh_flags, 0, 0); @@ -652,13 +726,14 @@ mesh_new_callback(struct mesh_area* mesh } } /* add reply to s */ - if(!mesh_state_add_cb(s, edns, buf, cb, cb_arg, qid, qflags)) { + if(!mesh_state_add_cb(s, edns, buf, cb, cb_arg, qid, qflags, &add_cb)) { if(added) mesh_state_delete(&s->s); return 0; } /* add serve expired timer if not already there */ if(timeout && !mesh_serve_expired_init(s, timeout)) { + mesh_remove_callback_without_accounting(s, add_cb); if(added) mesh_state_delete(&s->s); return 0; @@ -669,6 +744,7 @@ mesh_new_callback(struct mesh_area* mesh (mesh->env->cachedb_enabled && mesh->env->cfg->cachedb_check_when_serve_expired)) { if(!mesh_serve_expired_init(s, -1)) { + mesh_remove_callback_without_accounting(s, add_cb); if(added) mesh_state_delete(&s->s); return 0; @@ -684,6 +760,8 @@ mesh_new_callback(struct mesh_area* mesh mesh->num_reply_states ++; } mesh->num_reply_addrs++; + if(unique_info) + *unique_info = s->unique; if(added) mesh_run(mesh, s, module_event_new, NULL); return 1; @@ -887,33 +965,9 @@ void mesh_report_reply(struct mesh_area* 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* +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) @@ -932,20 +986,13 @@ mesh_copy_client_info(struct regional* r 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; itag_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; - } - } - } + /* tag_datas is owned by the matched acl_addr in config_file; its + * lifetime is until config reload, which tears down all mesh states + * first. Keep the original pointer so client_info_compare() + * can recognise two states from the same ACL entry. */ + /* fast reload insists on dropping the queries when interface-tag-data + * or access-control-tag-data are changed. */ + /* client_info->tag_datas already copied by regional_alloc_init above */ 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 @@ -955,6 +1002,11 @@ mesh_copy_client_info(struct regional* r cinfo->view->name); if(!client_info->view_name) return NULL; + } else if(cinfo->view_name) { + client_info->view_name = regional_strdup(region, + cinfo->view_name); + if(!client_info->view_name) + return NULL; } return client_info; } @@ -1022,6 +1074,7 @@ mesh_state_create(struct module_env* env mstate->s.no_cache_store = 0; mstate->s.need_refetch = 0; mstate->s.was_ratelimited = 0; + mstate->s.error_response_cache = 0; mstate->s.qstarttime = *env->now; /* init modules */ @@ -1044,6 +1097,18 @@ mesh_state_make_unique(struct mesh_state mstate->unique = mstate; } +/** pop a reply from the reply list, if there are any. */ +static struct mesh_reply* +mesh_reply_list_pop_first(struct mesh_state* mstate) +{ + if(mstate->reply_list) { + struct mesh_reply* r = mstate->reply_list; + mstate->reply_list = r->next; + return r; + } + return NULL; +} + void mesh_state_cleanup(struct mesh_state* mstate) { @@ -1059,17 +1124,30 @@ mesh_state_cleanup(struct mesh_state* ms } /* drop unsent replies */ if(!mstate->replies_sent) { - struct mesh_reply* rep = mstate->reply_list; + struct mesh_reply* rep; struct mesh_cb* cb; - /* in tcp_req_info, the mstates linked are removed, but - * the reply_list is now NULL, so the remove-from-empty-list - * takes no time and also it does not do the mesh accounting */ - mstate->reply_list = NULL; - for(; rep; rep=rep->next) { + /* Pop items from the list, that means there is no iterator. + * And then items can be removed from the reply list, from + * like comm_point_drop_reply and comm_point_close calls. + * As the tcp_req_info and http2 code drops the entire + * connection. That could delete mesh_reply items previous and + * after the current state. The previous items are already + * popped. And the next items can be altered, like to when a + * connection has more replies on the reply list. + * The current item is also popped so the code needs to + * remove its references. */ + while((rep = mesh_reply_list_pop_first(mstate)) != NULL) { infra_wait_limit_dec(mesh->env->infra_cache, &rep->query_reply, mesh->env->cfg); - if(rep->query_reply.c->use_h2) + if(rep->query_reply.c->tcp_req_info) + tcp_req_info_remove_mesh_state( + rep->query_reply.c->tcp_req_info, + mstate); + else if(rep->query_reply.c->use_h2) http2_stream_remove_mesh_state(rep->h2_stream); + else if(rep->query_reply.doq_stream) + doq_stream_remove_mesh_state( + rep->query_reply.doq_stream); comm_point_drop_reply(&rep->query_reply); log_assert(mesh->num_reply_addrs > 0); mesh->num_reply_addrs--; @@ -1152,8 +1230,7 @@ mesh_detect_cycle_found(struct module_qs { struct mesh_state* cyc_m = qstate->mesh_info; size_t counter = 0; - if(!dep_m) - return 0; + log_assert(dep_m); if(dep_m == cyc_m || find_in_subsub(dep_m, cyc_m, &counter)) { if(counter > MESH_MAX_SUBSUB) return 2; @@ -1190,28 +1267,26 @@ void mesh_detach_subs(struct module_qsta } int mesh_add_sub(struct module_qstate* qstate, struct query_info* qinfo, - uint16_t qflags, int prime, int valrec, struct module_qstate** newq, - struct mesh_state** sub) + struct respip_client_info* cinfo, uint16_t qflags, int prime, + int valrec, struct module_qstate** newq, struct mesh_state** sub) { /* find it, if not, create it */ struct mesh_area* mesh = qstate->env->mesh; - *sub = mesh_area_find(mesh, NULL, qinfo, qflags, - prime, valrec); - if(mesh_detect_cycle_found(qstate, *sub)) { - verbose(VERB_ALGO, "attach failed, cycle detected"); - return 0; - } + *sub = mesh_area_find(mesh, cinfo, qinfo, qflags, prime, valrec); if(!*sub) { #ifdef UNBOUND_DEBUG struct rbnode_type* n; #endif /* create a new one */ - *sub = mesh_state_create(qstate->env, qinfo, NULL, qflags, prime, - valrec); + *sub = mesh_state_create(qstate->env, qinfo, cinfo, qflags, + prime, valrec); if(!*sub) { log_err("mesh_attach_sub: out of memory"); return 0; } + /* inherit RPZ passthru from the parent so respip on the sub + * sees the same client-IP/qname PASSTHRU decision */ + (*sub)->s.rpz_passthru = qstate->rpz_passthru; #ifdef UNBOUND_DEBUG n = #else @@ -1230,18 +1305,25 @@ int mesh_add_sub(struct module_qstate* q rbtree_insert(&mesh->run, &(*sub)->run_node); log_assert(n != NULL); *newq = &(*sub)->s; - } else + } else { *newq = NULL; + if(mesh_detect_cycle_found(qstate, *sub)) { + verbose(VERB_ALGO, "attach failed, cycle detected"); + return 0; + } + } return 1; } int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo, - uint16_t qflags, int prime, int valrec, struct module_qstate** newq) + struct respip_client_info* cinfo, uint16_t qflags, int prime, + int valrec, struct module_qstate** newq) { struct mesh_area* mesh = qstate->env->mesh; struct mesh_state* sub = NULL; int was_detached; - if(!mesh_add_sub(qstate, qinfo, qflags, prime, valrec, newq, &sub)) + if(!mesh_add_sub(qstate, qinfo, cinfo, qflags, prime, valrec, newq, + &sub)) return 0; was_detached = (sub->super_set.count == 0); if(!mesh_state_attachment(qstate->mesh_info, sub)) @@ -1429,12 +1511,6 @@ mesh_send_reply(struct mesh_state* m, in struct timeval end_time; struct timeval duration; int secure; - /* briefly set the replylist to null in case the - * meshsendreply calls tcpreqinfo sendreply that - * comm_point_drops because of size, and then the - * null stops the mesh state remove and thus - * reply_list modification and accounting */ - struct mesh_reply* rlist = m->reply_list; /* rpz: apply actions */ rcode = mesh_is_udp(r) && mesh_is_rpz_respip_tcponly_action(m) @@ -1460,6 +1536,10 @@ mesh_send_reply(struct mesh_state* m, in * for HTTP/2 stream to refer to mesh state, in case * connection gets cleanup before HTTP/2 stream close. */ r->h2_stream->mesh_state = NULL; +#ifdef HAVE_NGTCP2 + } else if(r->query_reply.doq_stream) { + r->query_reply.doq_stream->mesh_state = NULL; +#endif } /* send the reply */ /* We don't reuse the encoded answer if: @@ -1487,9 +1567,7 @@ mesh_send_reply(struct mesh_state* m, in sldns_buffer_write_at(r_buffer, 0, &r->qid, sizeof(uint16_t)); sldns_buffer_write_at(r_buffer, 12, r->qname, m->s.qinfo.qname_len); - m->reply_list = NULL; comm_point_send_reply(&r->query_reply); - m->reply_list = rlist; } else if(rcode) { m->s.qinfo.qname = r->qname; m->s.qinfo.local_alias = r->local_alias; @@ -1511,9 +1589,7 @@ mesh_send_reply(struct mesh_state* m, in } error_encode(r_buffer, rcode, &m->s.qinfo, r->qid, r->qflags, &r->edns); - m->reply_list = NULL; comm_point_send_reply(&r->query_reply); - m->reply_list = rlist; } else { size_t udp_size = r->edns.udp_size; r->edns.edns_version = EDNS_ADVERTISED_VERSION; @@ -1549,9 +1625,7 @@ mesh_send_reply(struct mesh_state* m, in error_encode(r_buffer, LDNS_RCODE_SERVFAIL, &m->s.qinfo, r->qid, r->qflags, &r->edns); } - m->reply_list = NULL; comm_point_send_reply(&r->query_reply); - m->reply_list = rlist; } infra_wait_limit_dec(m->s.env->infra_cache, &r->query_reply, m->s.env->cfg); @@ -1614,9 +1688,9 @@ static void dns_error_reporting(struct m 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) { + agent_domain_len = dname_valid(agent_domain, opt->opt_len); + if(agent_domain_len < 3) { /* The agent domain needs to be a valid dname that is not the * root; from RFC9567. */ return; @@ -1684,7 +1758,7 @@ static void dns_error_reporting(struct m 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)) { + if(mesh_add_sub(qstate, &qinfo, NULL, BIT_RD, 0, 0, &newq, &sub)) { qstate->env->mesh->num_dns_error_reports++; } return; @@ -1703,6 +1777,7 @@ void mesh_query_done(struct mesh_state* struct reply_info* rep = (mstate->s.return_msg? mstate->s.return_msg->rep:NULL); struct timeval tv = {0, 0}; + struct mesh_area* mesh = mstate->s.env->mesh; int i = 0; /* No need for the serve expired timer anymore; we are going to reply. */ if(mstate->s.serve_expired_data) { @@ -1723,32 +1798,53 @@ void mesh_query_done(struct mesh_state* } } - if(mstate->reply_list && mstate->s.env->cfg->dns_error_reporting) + if(mstate->reply_list && mstate->s.env->cfg->dns_error_reporting + && (!rep || rep->security != sec_status_secure)) 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); - if(mstate->s.env->cfg->discard_timeout != 0 && - ((int)old.tv_sec)*1000+((int)old.tv_usec)/1000 > - mstate->s.env->cfg->discard_timeout) { - /* Drop the reply, it is too old */ - /* briefly set the reply_list to NULL, so that the - * tcp req info cleanup routine that calls the mesh - * to deregister the meshstate for it is not done - * because the list is NULL and also accounting is not - * done there, but instead we do that here. */ - struct mesh_reply* reply_list = mstate->reply_list; - verbose(VERB_ALGO, "drop reply, it is older than discard-timeout"); - infra_wait_limit_dec(mstate->s.env->infra_cache, - &r->query_reply, mstate->s.env->cfg); - mstate->reply_list = NULL; - if(r->query_reply.c->use_h2) - http2_stream_remove_mesh_state(r->h2_stream); - comm_point_drop_reply(&r->query_reply); - mstate->reply_list = reply_list; - mstate->s.env->mesh->num_queries_discard_timeout++; - continue; + while((r = mesh_reply_list_pop_first(mstate)) != NULL) { + + /* it was not detached (because it had a reply list), could be now */ + if(!mstate->reply_list && !mstate->cb_list + && mstate->super_set.count == 0) { + mesh->num_detached_states++; + } + /* if not replies any more in mstate, it is no longer a reply_state */ + if(!mstate->reply_list && !mstate->cb_list) { + log_assert(mesh->num_reply_states > 0); + mesh->num_reply_states--; + } + if(mesh_is_udp(r)) { + /* For UDP queries, the old replies are discarded. + * This stops a large volume of old replies from + * building up. + * The stream replies, are not discarded. The + * stream is open, the other side is waiting. + * Some answer is needed, even if servfail, but the + * real reply is ready to go, so that is given. */ + struct timeval old; + timeval_subtract(&old, mstate->s.env->now_tv, &r->start_time); + if(mstate->s.env->cfg->discard_timeout != 0 && + ((int)old.tv_sec)*1000+((int)old.tv_usec)/1000 > + mstate->s.env->cfg->discard_timeout) { + /* Drop the reply, it is too old */ + verbose(VERB_ALGO, "drop reply, it is older than discard-timeout"); + infra_wait_limit_dec(mstate->s.env->infra_cache, + &r->query_reply, mstate->s.env->cfg); + if(r->query_reply.c->tcp_req_info) + tcp_req_info_remove_mesh_state( + r->query_reply.c->tcp_req_info, + mstate); + else if(r->query_reply.c->use_h2) + http2_stream_remove_mesh_state(r->h2_stream); + else if(r->query_reply.doq_stream) + doq_stream_remove_mesh_state(r->query_reply.doq_stream); + comm_point_drop_reply(&r->query_reply); + log_assert(mstate->s.env->mesh->num_reply_addrs > 0); + mstate->s.env->mesh->num_reply_addrs--; + mstate->s.env->mesh->num_queries_discard_timeout++; + continue; + } } i++; @@ -1768,20 +1864,19 @@ void mesh_query_done(struct mesh_state* /* if this query is determined to be dropped during the * mesh processing, this is the point to take that action. */ if(mstate->s.is_drop) { - /* briefly set the reply_list to NULL, so that the - * tcp req info cleanup routine that calls the mesh - * to deregister the meshstate for it is not done - * because the list is NULL and also accounting is not - * done there, but instead we do that here. */ - struct mesh_reply* reply_list = mstate->reply_list; infra_wait_limit_dec(mstate->s.env->infra_cache, &r->query_reply, mstate->s.env->cfg); - mstate->reply_list = NULL; - if(r->query_reply.c->use_h2) { + if(r->query_reply.c->tcp_req_info) { + tcp_req_info_remove_mesh_state( + r->query_reply.c->tcp_req_info, mstate); + } else if(r->query_reply.c->use_h2) { http2_stream_remove_mesh_state(r->h2_stream); + } else if(r->query_reply.doq_stream) { + doq_stream_remove_mesh_state(r->query_reply.doq_stream); } comm_point_drop_reply(&r->query_reply); - mstate->reply_list = reply_list; + log_assert(mstate->s.env->mesh->num_reply_addrs > 0); + mstate->s.env->mesh->num_reply_addrs--; } else { struct sldns_buffer* r_buffer = r->query_reply.c->buffer; if(r->query_reply.c->tcp_req_info) { @@ -1820,18 +1915,6 @@ void mesh_query_done(struct mesh_state* } } - /* Mesh area accounting */ - if(mstate->reply_list) { - mstate->reply_list = NULL; - if(!mstate->reply_list && !mstate->cb_list) { - /* was a reply state, not anymore */ - log_assert(mstate->s.env->mesh->num_reply_states > 0); - mstate->s.env->mesh->num_reply_states--; - } - if(!mstate->reply_list && !mstate->cb_list && - mstate->super_set.count == 0) - mstate->s.env->mesh->num_detached_states++; - } mstate->replies_sent = 1; while((c = mstate->cb_list) != NULL) { @@ -1889,6 +1972,25 @@ struct mesh_state* mesh_area_find(struct return result; } +struct mesh_state* mesh_area_find_unique(struct mesh_area* mesh, + struct respip_client_info* cinfo, struct query_info* qinfo, + uint16_t qflags, int prime, int valrec, void* unique_info) +{ + struct mesh_state key; + struct mesh_state* result; + + key.node.key = &key; + key.s.is_priming = prime; + key.s.is_valrec = valrec; + key.s.qinfo = *qinfo; + key.s.query_flags = qflags; + key.unique = (struct mesh_state*)unique_info; + key.s.client_info = cinfo; + + result = (struct mesh_state*)rbtree_search(&mesh->all, &key); + return result; +} + /** remove mesh state callback */ int mesh_state_del_cb(struct mesh_state* s, mesh_cb_func_type cb, void* cb_arg) { @@ -1910,7 +2012,7 @@ int mesh_state_del_cb(struct mesh_state* 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) + uint16_t qid, uint16_t qflags, struct mesh_cb** result) { struct mesh_cb* r = regional_alloc(s->s.region, sizeof(struct mesh_cb)); @@ -1934,13 +2036,14 @@ int mesh_state_add_cb(struct mesh_state* r->qflags = qflags; r->next = s->cb_list; s->cb_list = r; + *result = r; return 1; } int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns, struct comm_reply* rep, uint16_t qid, uint16_t qflags, - const struct query_info* qinfo) + const struct query_info* qinfo, struct mesh_reply** result) { struct mesh_reply* r = regional_alloc(s->s.region, sizeof(struct mesh_reply)); @@ -1960,6 +2063,10 @@ int mesh_state_add_reply(struct mesh_sta r->qid = qid; r->qflags = qflags; r->start_time = *s->s.env->now_tv; + if(s->reply_list == NULL && !s->has_first_reply_time) { + s->first_reply_time = r->start_time; + s->has_first_reply_time = 1; + } r->next = s->reply_list; r->qname = regional_alloc_init(s->s.region, qinfo->qname, s->s.qinfo.qname_len); @@ -1968,6 +2075,8 @@ int mesh_state_add_reply(struct mesh_sta if(rep->c->use_h2) r->h2_stream = rep->c->h2_stream; else r->h2_stream = NULL; + if(rep->c->type != comm_doq) + r->query_reply.doq_stream = NULL; /* Data related to local alias stored in 'qinfo' (if any) is ephemeral * and can be different for different original queries (even if the @@ -2015,6 +2124,7 @@ int mesh_state_add_reply(struct mesh_sta r->local_alias = NULL; s->reply_list = r; + *result = r; return 1; } @@ -2172,8 +2282,29 @@ void mesh_run(struct mesh_area* mesh, st enum module_ev ev, struct outbound_entry* e) { enum module_ext_state s; + int numrun = 0; verbose(VERB_ALGO, "mesh_run: start"); while(mstate) { + if(numrun++ > MESH_MAX_RUN_ITER) { + /* These modules are too much to activate, stop them.*/ + log_err("Too many module run iterations, deleting"); + while(mstate) { + /* notify supers */ + if(mstate->super_set.count > 0) { + verbose(VERB_ALGO, "notify supers of failure"); + mstate->s.return_msg = NULL; + mstate->s.return_rcode = LDNS_RCODE_SERVFAIL; + mesh_walk_supers(mesh, mstate); + } + mesh_state_delete(&mstate->s); + if(mesh->run.count > 0) { + /* pop random element off the runnable tree */ + mstate = (struct mesh_state*)mesh->run.root->key; + (void)rbtree_delete(&mesh->run, mstate); + } else mstate = NULL; + } + break; + } /* run the module */ fptr_ok(fptr_whitelist_mod_operate( mesh->mods.mod[mstate->s.curmod]->operate)); @@ -2272,6 +2403,7 @@ mesh_stats_clear(struct mesh_area* mesh) 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_replyaddr_limit = 0; mesh->num_queries_wait_limit = 0; mesh->num_dns_error_reports = 0; } @@ -2297,7 +2429,7 @@ mesh_detect_cycle(struct module_qstate* struct mesh_area* mesh = qstate->env->mesh; struct mesh_state* dep_m = NULL; dep_m = mesh_area_find(mesh, NULL, qinfo, flags, prime, valrec); - return mesh_detect_cycle_found(qstate, dep_m); + return dep_m?mesh_detect_cycle_found(qstate, dep_m):0; } void mesh_list_insert(struct mesh_state* m, struct mesh_state** fp, @@ -2324,7 +2456,8 @@ void mesh_list_remove(struct mesh_state* } void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m, - struct comm_point* cp) + struct comm_point* cp, struct http2_stream* h2_stream, + struct doq_stream* doq_stream) { struct mesh_reply* n, *prev = NULL; n = m->reply_list; @@ -2332,7 +2465,9 @@ void mesh_state_remove_reply(struct mesh * there is no accounting twice */ if(!n) return; /* nothing to remove, also no accounting needed */ while(n) { - if(n->query_reply.c == cp) { + if(n->query_reply.c == cp + && (!h2_stream || n->h2_stream == h2_stream) + && (!doq_stream || n->query_reply.doq_stream == doq_stream)) { /* unlink it */ if(prev) prev->next = n->next; else m->reply_list = n->next; @@ -2341,6 +2476,14 @@ void mesh_state_remove_reply(struct mesh mesh->num_reply_addrs--; infra_wait_limit_dec(mesh->env->infra_cache, &n->query_reply, mesh->env->cfg); + /* We may be removing more than one http2 stream (they + * share the same comm_point); make sure the streams + * don't point back. */ + if(n->h2_stream) n->h2_stream->mesh_state = NULL; +#ifdef HAVE_NGTCP2 + if(n->query_reply.doq_stream) + n->query_reply.doq_stream->mesh_state = NULL; +#endif /* prev = prev; */ n = n->next; @@ -2361,7 +2504,6 @@ void mesh_state_remove_reply(struct mesh } } - static int apply_respip_action(struct module_qstate* qstate, const struct query_info* qinfo, struct respip_client_info* cinfo, @@ -2381,9 +2523,10 @@ apply_respip_action(struct module_qstate /* xxx_deny actions mean dropping the reply, unless the original reply * was redirected to response-ip data. */ - if((actinfo->action == respip_deny || + if(actinfo->action == respip_always_deny || + ((actinfo->action == respip_deny || actinfo->action == respip_inform_deny) && - *encode_repp == rep) + *encode_repp == rep)) *encode_repp = NULL; return 1; @@ -2448,12 +2591,15 @@ mesh_serve_expired_callback(void* arg) qstate->client_info, &actinfo, msg->rep, &alias_rrset, &encode_rep, qstate->env->auth_zones)) { return; - } else if(partial_rep && - !respip_merge_cname(partial_rep, &qstate->qinfo, msg->rep, + } else if(partial_rep) { + if(!respip_merge_cname(partial_rep, &qstate->qinfo, msg->rep, qstate->client_info, must_validate, &encode_rep, qstate->region, qstate->env->auth_zones, qstate->env->views, qstate->env->respip_set)) { - return; + return; + } + /* merge succeeded; final reply, no further alias pass */ + partial_rep = NULL; } if(!encode_rep || alias_rrset) { if(!encode_rep) { @@ -2464,6 +2610,7 @@ mesh_serve_expired_callback(void* arg) partial_rep = encode_rep; } } + msg->rep = encode_rep; /* We've found a partial reply ending with an * alias. Replace the lookup qinfo for the * alias target and lookup the cache again to @@ -2489,29 +2636,41 @@ mesh_serve_expired_callback(void* arg) if(verbosity >= VERB_ALGO) log_dns_msg("Serve expired lookup", &qstate->qinfo, msg->rep); - for(r = mstate->reply_list; r; r = r->next) { - struct timeval old; - timeval_subtract(&old, mstate->s.env->now_tv, &r->start_time); - if(mstate->s.env->cfg->discard_timeout != 0 && + while((r = mesh_reply_list_pop_first(mstate)) != NULL) { + + /* it was not detached (because it had a reply list), could be now */ + if(!mstate->reply_list && !mstate->cb_list + && mstate->super_set.count == 0) { + mesh->num_detached_states++; + } + /* if not replies any more in mstate, it is no longer a reply_state */ + if(!mstate->reply_list && !mstate->cb_list) { + log_assert(mesh->num_reply_states > 0); + mesh->num_reply_states--; + } + if(mesh_is_udp(r)) { + struct timeval old; + timeval_subtract(&old, mstate->s.env->now_tv, &r->start_time); + if(mstate->s.env->cfg->discard_timeout != 0 && ((int)old.tv_sec)*1000+((int)old.tv_usec)/1000 > mstate->s.env->cfg->discard_timeout) { /* Drop the reply, it is too old */ - /* briefly set the reply_list to NULL, so that the - * tcp req info cleanup routine that calls the mesh - * to deregister the meshstate for it is not done - * because the list is NULL and also accounting is not - * done there, but instead we do that here. */ - struct mesh_reply* reply_list = mstate->reply_list; verbose(VERB_ALGO, "drop reply, it is older than discard-timeout"); infra_wait_limit_dec(mstate->s.env->infra_cache, &r->query_reply, mstate->s.env->cfg); - mstate->reply_list = NULL; - if(r->query_reply.c->use_h2) + if(r->query_reply.c->tcp_req_info) + tcp_req_info_remove_mesh_state( + r->query_reply.c->tcp_req_info, mstate); + else if(r->query_reply.c->use_h2) http2_stream_remove_mesh_state(r->h2_stream); + else if(r->query_reply.doq_stream) + doq_stream_remove_mesh_state(r->query_reply.doq_stream); comm_point_drop_reply(&r->query_reply); - mstate->reply_list = reply_list; + log_assert(mstate->s.env->mesh->num_reply_addrs > 0); + mstate->s.env->mesh->num_reply_addrs--; mstate->s.env->mesh->num_queries_discard_timeout++; continue; + } } i++; @@ -2544,8 +2703,7 @@ mesh_serve_expired_callback(void* arg) if(r->query_reply.c->tcp_req_info) tcp_req_info_remove_mesh_state(r->query_reply.c->tcp_req_info, mstate); /* mesh_send_reply removed mesh state from http2_stream. */ - infra_wait_limit_dec(mstate->s.env->infra_cache, - &r->query_reply, mstate->s.env->cfg); + /* mesh_send_reply decremented wait_limit. */ prev = r; prev_buffer = r_buffer; } @@ -2564,18 +2722,6 @@ mesh_serve_expired_callback(void* arg) } } - /* Mesh area accounting */ - if(mstate->reply_list) { - mstate->reply_list = NULL; - if(!mstate->reply_list && !mstate->cb_list) { - log_assert(mesh->num_reply_states > 0); - mesh->num_reply_states--; - if(mstate->super_set.count == 0) { - mesh->num_detached_states++; - } - } - } - while((c = mstate->cb_list) != NULL) { /* take this cb off the list; so that the list can be * changed, eg. by adds from the callback routine */ @@ -2608,13 +2754,30 @@ int mesh_jostle_exceeded(struct mesh_are } void mesh_remove_callback(struct mesh_area* mesh, struct query_info* qinfo, - uint16_t qflags, mesh_cb_func_type cb, void* cb_arg) + uint16_t qflags, mesh_cb_func_type cb, void* cb_arg, void* unique_info) { 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; + if(s && mesh_state_del_cb(s, cb, cb_arg)) + goto removed; + if(unique_info) { + s = mesh_area_find_unique(mesh, NULL, qinfo, + qflags&(BIT_RD|BIT_CD), 0, 0, unique_info); + if(s && mesh_state_del_cb(s, cb, cb_arg)) + goto removed; + } + /* mesh_area_find builds key.unique=NULL and cannot match a state + * created with mesh_state_make_unique (e.g. subnetcache sets + * env->unique_mesh). Fall back to a linear scan; cb+cb_arg is an + * exact key (mesh_state_del_cb compares both). + * This works for both lookups for zonemd and for hostname authzone. */ + RBTREE_FOR(s, struct mesh_state*, &mesh->all) { + if(s->cb_list && mesh_state_del_cb(s, cb, cb_arg)) + goto removed; + } + return; +removed: /* It was in the list and removed. */ log_assert(mesh->num_reply_addrs > 0); mesh->num_reply_addrs--; Index: sbin/unwind/libunbound/services/mesh.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/services/mesh.h,v diff -u -p -r1.11 mesh.h --- sbin/unwind/libunbound/services/mesh.h 29 Sep 2025 14:53:38 -0000 1.11 +++ sbin/unwind/libunbound/services/mesh.h 21 Sep 2026 16:28:24 -0000 @@ -70,6 +70,13 @@ struct respip_client_info; #define MESH_MAX_ACTIVATION 10000 /** + * Maximum number of mesh state run items. These are different modules + * activated during a mesh run. Any more is likely an infinite loop + * in the module. It is then terminated, and states are deleted. + */ +#define MESH_MAX_RUN_ITER 10000 + +/** * Max number of references-to-references-to-references.. search size. * Any more is treated like 'too large', and the creation of a new * dependency is failed (so that no loops can be created). @@ -141,6 +148,8 @@ struct mesh_area { 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 replyaddr limit */ + size_t num_queries_replyaddr_limit; /** stats, number of queries removed due to wait-limit */ size_t num_queries_wait_limit; /** stats, number of dns error reports generated */ @@ -189,6 +198,12 @@ struct mesh_state { struct module_qstate s; /** the list of replies to clients for the results */ struct mesh_reply* reply_list; + /** if it has a first reply time */ + int has_first_reply_time; + /** wall-clock time the first client reply was attached; + * used by mesh_make_new_space() so duplicate retransmits + * cannot reset jostle aging. */ + struct timeval first_reply_time; /** the list of callbacks for the results */ struct mesh_cb* cb_list; /** set of superstates (that want this state's result) @@ -334,11 +349,14 @@ void mesh_new_client(struct mesh_area* m * @param cb_arg: callback user arg. * @param rpz_passthru: if true, the rpz passthru was previously found and * further rpz processing is stopped. + * @param unique_info: if nonnull, unique info is passed back to be used + * for the callback remove call. It does not need to be deallocated. * @return 0 on error. */ int mesh_new_callback(struct mesh_area* mesh, struct query_info* qinfo, uint16_t qflags, struct edns_data* edns, struct sldns_buffer* buf, - uint16_t qid, mesh_cb_func_type cb, void* cb_arg, int rpz_passthru); + uint16_t qid, mesh_cb_func_type cb, void* cb_arg, int rpz_passthru, + void** unique_info); /** * New prefetch message. Create new query state if needed. @@ -399,6 +417,8 @@ void mesh_detach_subs(struct module_qsta * @param qstate: the state to find mesh state, and that wants to receive * the results from the new subquery. * @param qinfo: what to query for (copied). + * @param cinfo: if non-NULL client specific info that may affect IP-based + * actions that apply to the query result. It is copied. * @param qflags: what flags to use (RD / CD flag or not). * @param prime: if it is a (stub) priming query. * @param valrec: if it is a validation recursion query (lookup of key, DS). @@ -407,7 +427,8 @@ void mesh_detach_subs(struct module_qsta * @return: false on error, true if success (and init may be needed). */ int mesh_attach_sub(struct module_qstate* qstate, struct query_info* qinfo, - uint16_t qflags, int prime, int valrec, struct module_qstate** newq); + struct respip_client_info* cinfo, uint16_t qflags, int prime, + int valrec, struct module_qstate** newq); /** * Add detached query. @@ -426,6 +447,8 @@ int mesh_attach_sub(struct module_qstate * @param qstate: the state to find mesh state, and that wants to receive * the results from the new subquery. * @param qinfo: what to query for (copied). + * @param cinfo: if non-NULL client specific info that may affect IP-based + * actions that apply to the query result. It is copied. * @param qflags: what flags to use (RD / CD flag or not). * @param prime: if it is a (stub) priming query. * @param valrec: if it is a validation recursion query (lookup of key, DS). @@ -435,8 +458,8 @@ int mesh_attach_sub(struct module_qstate * @return: false on error, true if success (and init may be needed). */ int mesh_add_sub(struct module_qstate* qstate, struct query_info* qinfo, - uint16_t qflags, int prime, int valrec, struct module_qstate** newq, - struct mesh_state** sub); + struct respip_client_info* cinfo, uint16_t qflags, int prime, + int valrec, struct module_qstate** newq, struct mesh_state** sub); /** * Query state is done, send messages to reply entries. @@ -531,6 +554,23 @@ struct mesh_state* mesh_area_find(struct uint16_t qflags, int prime, int valrec); /** + * Find a unique mesh state in the mesh area. Pass relevant flags. + * + * @param mesh: the mesh area to look in. + * @param cinfo: if non-NULL client specific info that may affect IP-based + * actions that apply to the query result. + * @param qinfo: what query + * @param qflags: if RD / CD bit is set or not. + * @param prime: if it is a priming query. + * @param valrec: if it is a validation-recursion query. + * @param unique_info: the unique info for the state. NULL can be passed. + * @return: mesh state or NULL if not found. + */ +struct mesh_state* mesh_area_find_unique(struct mesh_area* mesh, + struct respip_client_info* cinfo, struct query_info* qinfo, + uint16_t qflags, int prime, int valrec, void* unique_info); + +/** * Setup attachment super/sub relation between super and sub mesh state. * The relation must not be present when calling the function. * Does not update stat items in mesh_area. @@ -549,11 +589,12 @@ int mesh_state_attachment(struct mesh_st * @param qid: ID of reply. * @param qflags: original query flags. * @param qinfo: original query info. + * @param result: the allocated reply structure, for rollback. * @return: 0 on alloc error. */ int mesh_state_add_reply(struct mesh_state* s, struct edns_data* edns, struct comm_reply* rep, uint16_t qid, uint16_t qflags, - const struct query_info* qinfo); + const struct query_info* qinfo, struct mesh_reply** result); /** * Create new callback structure and attach it to a mesh state. @@ -565,11 +606,12 @@ int mesh_state_add_reply(struct mesh_sta * @param cb_arg: callback user arg. * @param qid: ID of reply. * @param qflags: original query flags. + * @param result: the allocated callback structure, for rollback. * @return: 0 on alloc error. */ int mesh_state_add_cb(struct mesh_state* s, struct edns_data* edns, struct sldns_buffer* buf, mesh_cb_func_type cb, void* cb_arg, - uint16_t qid, uint16_t qflags); + uint16_t qid, uint16_t qflags, struct mesh_cb** result); /** * Run the mesh. Run all runnable mesh states. Which can create new @@ -670,9 +712,14 @@ void mesh_list_remove(struct mesh_state* * @param mesh: to update the counters. * @param m: the mesh state. * @param cp: the comm_point to remove from the list. + * @param h2_stream: if not NULL, it specifies the h2_stream to match + * for the delete. + * @param doq_stream: if not NULL, it specifies the doq_stream to match + * for the delete. */ void mesh_state_remove_reply(struct mesh_area* mesh, struct mesh_state* m, - struct comm_point* cp); + struct comm_point* cp, struct http2_stream* h2_stream, + struct doq_stream* doq_stream); /** Callback for when the serve expired client timer has run out. Tries to * find an expired answer in the cache and reply that to the client. @@ -719,8 +766,13 @@ void mesh_respond_serve_expired(struct m * @param qflags: flags from client query. * @param cb: callback function. * @param cb_arg: callback user arg. + * @param unique_info: if not NULL, used to find a unique state for removal. */ void mesh_remove_callback(struct mesh_area* mesh, struct query_info* qinfo, - uint16_t qflags, mesh_cb_func_type cb, void* cb_arg); + uint16_t qflags, mesh_cb_func_type cb, void* cb_arg, void* unique_info); + +/** Copy the client info to the query region. */ +struct respip_client_info* mesh_copy_client_info(struct regional* region, + struct respip_client_info* cinfo); #endif /* SERVICES_MESH_H */ Index: sbin/unwind/libunbound/services/modstack.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/services/modstack.c,v diff -u -p -r1.9 modstack.c --- sbin/unwind/libunbound/services/modstack.c 29 Sep 2025 14:53:38 -0000 1.9 +++ sbin/unwind/libunbound/services/modstack.c 21 Sep 2026 16:28:24 -0000 @@ -232,7 +232,7 @@ module_func_block* module_factory(const return NULL; } -int +int modstack_call_startup(struct module_stack* stack, const char* module_conf, struct module_env* env) { @@ -262,6 +262,7 @@ int modstack_call_init(struct module_stack* stack, const char* module_conf, struct module_env* env) { + const char* orig_module_conf = module_conf; int i, changed = 0; env->need_to_validate = 0; /* set by module init below */ for(i=0; inum; i++) { @@ -276,11 +277,13 @@ modstack_call_init(struct module_stack* changed = 1; } } - module_conf += strlen(stack->mod[i]->name); + /* Skip this module name in module_conf. */ + while(*module_conf && !isspace((unsigned char)*module_conf)) + module_conf++; } if(changed) { modstack_free(stack); - if(!modstack_config(stack, module_conf)) { + if(!modstack_config(stack, orig_module_conf)) { return 0; } } @@ -298,7 +301,7 @@ modstack_call_init(struct module_stack* return 1; } -void +void modstack_call_deinit(struct module_stack* stack, struct module_env* env) { int i; @@ -320,7 +323,7 @@ modstack_call_destartup(struct module_st } } -int +int modstack_find(struct module_stack* stack, const char* name) { int i; Index: sbin/unwind/libunbound/services/outside_network.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/services/outside_network.c,v diff -u -p -r1.20 outside_network.c --- sbin/unwind/libunbound/services/outside_network.c 29 Sep 2025 14:53:38 -0000 1.20 +++ sbin/unwind/libunbound/services/outside_network.c 21 Sep 2026 16:28:25 -0000 @@ -160,6 +160,19 @@ reuse_cmp_addrportssl(const void* key1, return 1; if(!r1->is_ssl && r2->is_ssl) return -1; + + /* compare tls_auth_name if SSL-enabled */ + if(r1->is_ssl) { + if(r1->tls_auth_name && !r2->tls_auth_name) + return 1; + if(!r1->tls_auth_name && r2->tls_auth_name) + return -1; + if(r1->tls_auth_name && r2->tls_auth_name) { + r = strcmp(r1->tls_auth_name, r2->tls_auth_name); + if(r != 0) + return r; + } + } return 0; } @@ -195,6 +208,7 @@ static void waiting_tcp_delete(struct waiting_tcp* w) { if(!w) return; + free(w->tls_auth_name); if(w->timer) comm_timer_delete(w->timer); free(w); @@ -531,7 +545,7 @@ reuse_tcp_insert(struct outside_network* /** find reuse tcp stream to destination for query, or NULL if none */ static struct reuse_tcp* reuse_tcp_find(struct outside_network* outnet, struct sockaddr_storage* addr, - socklen_t addrlen, int use_ssl) + socklen_t addrlen, int use_ssl, char* tls_auth_name) { struct waiting_tcp key_w; struct pending_tcp key_p; @@ -545,8 +559,10 @@ reuse_tcp_find(struct outside_network* o key_p.c = &c; key_p.reuse.pending = &key_p; key_p.reuse.node.key = &key_p.reuse; - if(use_ssl) + if(use_ssl) { key_p.reuse.is_ssl = 1; + key_p.reuse.tls_auth_name = tls_auth_name; + } if(addrlen > (socklen_t)sizeof(key_p.reuse.addr)) return NULL; memmove(&key_p.reuse.addr, addr, addrlen); @@ -646,6 +662,7 @@ static int outnet_tcp_take_into_use(struct waiting_tcp* w) { struct pending_tcp* pend = w->outnet->tcp_free; + char* tls_auth_name = NULL; int s; log_assert(pend); log_assert(w->pkt); @@ -746,7 +763,22 @@ outnet_tcp_take_into_use(struct waiting_ comm_point_tcp_win_bio_cb(pend->c, pend->c->ssl); #endif pend->c->ssl_shake_state = comm_ssl_shake_write; - if(!set_auth_name_on_ssl(pend->c->ssl, w->tls_auth_name, + if(w->tls_auth_name) { + /* strdup the auth name, while not linked the list yet, + * in case of failure, easy cleanup. */ + tls_auth_name = strdup(w->tls_auth_name); + if(!tls_auth_name) { + log_err("out of memory: alloc tls auth name"); + pend->c->fd = s; +#ifdef HAVE_SSL + SSL_free(pend->c->ssl); +#endif + pend->c->ssl = NULL; + comm_point_close(pend->c); + return 0; + } + } + if(!set_auth_name_on_ssl(pend->c->ssl, tls_auth_name, w->outnet->tls_use_sni)) { pend->c->fd = s; #ifdef HAVE_SSL @@ -754,6 +786,7 @@ outnet_tcp_take_into_use(struct waiting_ #endif pend->c->ssl = NULL; comm_point_close(pend->c); + free(tls_auth_name); return 0; } } @@ -778,9 +811,20 @@ outnet_tcp_take_into_use(struct waiting_ if(pend->reuse.node.key) reuse_tcp_remove_tree_list(w->outnet, &pend->reuse); - if(pend->c->ssl) + if(pend->c->ssl) { pend->reuse.is_ssl = 1; - else pend->reuse.is_ssl = 0; + if(pend->reuse.tls_auth_name) + free(pend->reuse.tls_auth_name); + pend->reuse.tls_auth_name = tls_auth_name; + tls_auth_name = NULL; + } else { + pend->reuse.is_ssl = 0; + if(pend->reuse.tls_auth_name) + free(pend->reuse.tls_auth_name); + pend->reuse.tls_auth_name = NULL; + } + /* free tls auth name if nonNULL */ + free(tls_auth_name); /* insert in reuse by address tree if not already inserted there */ (void)reuse_tcp_insert(w->outnet, pend); reuse_tree_by_id_insert(&pend->reuse, w); @@ -969,7 +1013,7 @@ use_free_buffer(struct outside_network* (!outnet->tcp_reuse_first && !outnet->tcp_reuse_last) || (outnet->tcp_reuse_first && outnet->tcp_reuse_last)); reuse = reuse_tcp_find(outnet, &w->addr, w->addrlen, - w->ssl_upstream); + w->ssl_upstream, w->tls_auth_name); /* re-select an ID when moving to a new TCP buffer */ w->id = tcp_select_id(outnet, reuse); LDNS_ID_SET(w->pkt, w->id); @@ -1198,6 +1242,10 @@ decommission_pending_tcp(struct outside_ /* needs unlink from the reuse tree to get deleted */ reuse_tcp_remove_tree_list(outnet, &pend->reuse); } + if(pend->reuse.tls_auth_name) { + free(pend->reuse.tls_auth_name); + pend->reuse.tls_auth_name = NULL; + } /* free SSL structure after remove from outnet tcp reuse tree, * because the c->ssl null or not is used for sorting in the tree */ if(pend->c->ssl) { @@ -1433,7 +1481,7 @@ portcomm_loweruse(struct outside_network pif = pc->pif; log_assert(pif->inuse > 0); #ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION - pif->avail_ports[pif->avail_total - pif->inuse] = pc->number; + shared_ports_return_port(outnet->shared_ports, pif->shpif, pc->number); #endif pif->inuse--; pif->out[pc->index] = pif->out[pif->inuse]; @@ -1647,19 +1695,25 @@ create_pending_tcp(struct outside_networ } /** setup an outgoing interface, ready address */ -static int setup_if(struct port_if* pif, const char* addrstr, - int* avail, int numavail, size_t numfd) +static int setup_if(struct port_if* pif, const char* addrstr, size_t numfd, + struct shared_ports* shp) { -#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION - pif->avail_total = numavail; - pif->avail_ports = (int*)memdup(avail, (size_t)numavail*sizeof(int)); - if(!pif->avail_ports) - return 0; -#endif if(!ipstrtoaddr(addrstr, UNBOUND_DNS_PORT, &pif->addr, &pif->addrlen) && !netblockstrtoaddr(addrstr, UNBOUND_DNS_PORT, &pif->addr, &pif->addrlen, &pif->pfxlen)) return 0; +#ifdef INT_MAX + if(numfd > (size_t)INT_MAX) { + log_err("num_ports exceeds INT_MAX"); + return 0; + } +#endif +#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION + pif->shpif = shared_ports_find_if(shp, &pif->addr, pif->addrlen, + pif->pfxlen); +#else + (void)shp; +#endif pif->maxout = (int)numfd; pif->inuse = 0; pif->out = (struct port_comm**)calloc(numfd, @@ -1673,12 +1727,12 @@ struct outside_network* outside_network_create(struct comm_base *base, size_t bufsize, size_t num_ports, char** ifs, int num_ifs, int do_ip4, int do_ip6, size_t num_tcp, int dscp, struct infra_cache* infra, - struct ub_randstate* rnd, int use_caps_for_id, int* availports, - int numavailports, size_t unwanted_threshold, int tcp_mss, + struct ub_randstate* rnd, int use_caps_for_id, + size_t unwanted_threshold, int tcp_mss, void (*unwanted_action)(void*), void* unwanted_param, int do_udp, void* sslctx, int delayclose, int tls_use_sni, struct dt_env* dtenv, int udp_connect, int max_reuse_tcp_queries, int tcp_reuse_timeout, - int tcp_auth_query_timeout) + int tcp_auth_query_timeout, struct shared_ports* shared_ports) { struct outside_network* outnet = (struct outside_network*) calloc(1, sizeof(struct outside_network)); @@ -1713,6 +1767,7 @@ outside_network_create(struct comm_base outnet->do_udp = do_udp; outnet->tcp_mss = tcp_mss; outnet->ip_dscp = dscp; + outnet->shared_ports = shared_ports; #ifndef S_SPLINT_S if(delayclose) { outnet->delayclose = 1; @@ -1723,11 +1778,18 @@ outside_network_create(struct comm_base if(udp_connect) { outnet->udp_connect = 1; } - if(numavailports == 0 || num_ports == 0) { + if(num_ports == 0) { log_err("no outgoing ports available"); outside_network_delete(outnet); return NULL; } +#ifdef INT_MAX + if(num_ports > (size_t)INT_MAX) { + log_err("outgoing num_ports exceeds INT_MAX"); + outside_network_delete(outnet); + return NULL; + } +#endif #ifndef INET6 do_ip6 = 0; #endif @@ -1784,13 +1846,13 @@ outside_network_create(struct comm_base /* allocate interfaces */ if(num_ifs == 0) { if(do_ip4 && !setup_if(&outnet->ip4_ifs[0], "0.0.0.0", - availports, numavailports, num_ports)) { + num_ports, outnet->shared_ports)) { log_err("malloc failed"); outside_network_delete(outnet); return NULL; } if(do_ip6 && !setup_if(&outnet->ip6_ifs[0], "::", - availports, numavailports, num_ports)) { + num_ports, outnet->shared_ports)) { log_err("malloc failed"); outside_network_delete(outnet); return NULL; @@ -1801,7 +1863,7 @@ outside_network_create(struct comm_base for(i=0; iip6_ifs[done_6], ifs[i], - availports, numavailports, num_ports)){ + num_ports, outnet->shared_ports)){ log_err("malloc failed"); outside_network_delete(outnet); return NULL; @@ -1810,7 +1872,7 @@ outside_network_create(struct comm_base } if(!str_is_ip6(ifs[i]) && do_ip4) { if(!setup_if(&outnet->ip4_ifs[done_4], ifs[i], - availports, numavailports, num_ports)){ + num_ports, outnet->shared_ports)){ log_err("malloc failed"); outside_network_delete(outnet); return NULL; @@ -1888,9 +1950,6 @@ outside_network_delete(struct outside_ne comm_point_delete(pc->cp); free(pc); } -#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION - free(outnet->ip4_ifs[i].avail_ports); -#endif free(outnet->ip4_ifs[i].out); } free(outnet->ip4_ifs); @@ -1904,9 +1963,6 @@ outside_network_delete(struct outside_ne comm_point_delete(pc->cp); free(pc); } -#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION - free(outnet->ip6_ifs[i].avail_ports); -#endif free(outnet->ip6_ifs[i].out); } free(outnet->ip6_ifs); @@ -1922,6 +1978,10 @@ outside_network_delete(struct outside_ne * the tcp conn is working on */ decommission_pending_tcp(outnet, pend); } + if(pend->reuse.tls_auth_name) { + free(pend->reuse.tls_auth_name); + pend->reuse.tls_auth_name = NULL; + } comm_point_delete(outnet->tcp_conns[i]->c); free(outnet->tcp_conns[i]); outnet->tcp_conns[i] = NULL; @@ -2112,7 +2172,10 @@ static int select_ifport(struct outside_network* outnet, struct pending* pend, int num_if, struct port_if* ifs) { - int my_if, my_port, fd, portno, inuse, tries=0; + int my_if, fd, portno, inuse, tries=0; +#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION + int reused; +#endif struct port_if* pif; /* randomly select interface and port */ if(num_if == 0) { @@ -2126,37 +2189,35 @@ select_ifport(struct outside_network* ou my_if = ub_random_max(outnet->rnd, num_if); pif = &ifs[my_if]; #ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION - if(outnet->udp_connect) { - /* if we connect() we cannot reuse fds for a port */ - if(pif->inuse >= pif->avail_total) { - tries++; - if(tries < MAX_PORT_RETRY) - continue; - log_err("failed to find an open port, drop msg"); - return 0; - } - my_port = pif->inuse + ub_random_max(outnet->rnd, - pif->avail_total - pif->inuse); - } else { - my_port = ub_random_max(outnet->rnd, pif->avail_total); - if(my_port < pif->inuse) { - /* port already open */ - pend->pc = pif->out[my_port]; - verbose(VERB_ALGO, "using UDP if=%d port=%d", - my_if, pend->pc->number); - break; - } + if(!shared_ports_fetch_random(outnet->shared_ports, + pif->shpif, outnet->rnd, outnet->udp_connect, + pif->inuse, &portno, &reused)) { + tries++; + if(tries < MAX_PORT_RETRY) + continue; + log_err("failed to find an open port, drop msg"); + return 0; + } + if(reused) { + /* port already open */ + log_assert(portno < pif->inuse); + pend->pc = pif->out[portno]; + verbose(VERB_ALGO, "using UDP if=%d port=%d", + my_if, pend->pc->number); + break; } - /* try to open new port, if fails, loop to try again */ - log_assert(pif->inuse < pif->maxout); - portno = pif->avail_ports[my_port - pif->inuse]; #else - my_port = portno = 0; + portno = 0; #endif + /* try to open new port, if fails, loop to try again */ fd = udp_sockport(&pif->addr, pif->addrlen, pif->pfxlen, portno, &inuse, outnet->rnd, outnet->ip_dscp); if(fd == -1 && !inuse) { /* nonrecoverable error making socket */ +#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION + shared_ports_return_port(outnet->shared_ports, + pif->shpif, portno); +#endif return 0; } if(fd != -1) { @@ -2173,6 +2234,11 @@ select_ifport(struct outside_network* ou pend->addrlen); } sock_close(fd); +#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION + shared_ports_return_port( + outnet->shared_ports, + pif->shpif, portno); +#endif return 0; } } @@ -2190,14 +2256,14 @@ select_ifport(struct outside_network* ou /* grab port in interface */ pif->out[pif->inuse] = pend->pc; -#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION - pif->avail_ports[my_port - pif->inuse] = - pif->avail_ports[pif->avail_total-pif->inuse-1]; -#endif pif->inuse++; break; } /* failed, already in use */ +#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION + shared_ports_return_port(outnet->shared_ports, pif->shpif, + portno); +#endif verbose(VERB_QUERY, "port %d in use, trying another", portno); tries++; if(tries == MAX_PORT_RETRY) { @@ -2447,7 +2513,7 @@ pending_tcp_query(struct serviced_query* /* find out if a reused stream to the target exists */ /* if so, take it into use */ reuse = reuse_tcp_find(sq->outnet, &sq->addr, sq->addrlen, - sq->ssl_upstream); + sq->ssl_upstream, sq->tls_auth_name); if(reuse) { log_reuse_tcp(VERB_CLIENT, "pending_tcp_query: found reuse", reuse); log_assert(reuse->pending); @@ -2489,7 +2555,16 @@ pending_tcp_query(struct serviced_query* w->cb = callback; w->cb_arg = callback_arg; w->ssl_upstream = sq->ssl_upstream; - w->tls_auth_name = sq->tls_auth_name; + if(sq->tls_auth_name) { + w->tls_auth_name = strdup(sq->tls_auth_name); + if(!w->tls_auth_name) { + comm_timer_delete(w->timer); + free(w); + return NULL; + } + } else { + w->tls_auth_name = NULL; + } w->timeout = timeout; w->id_node.key = NULL; w->write_wait_prev = NULL; @@ -3287,9 +3362,9 @@ serviced_udp_callback(struct comm_point* if(error == NETEVENT_TIMEOUT) { if(sq->status == serviced_query_UDP_EDNS && sq->last_rtt < 5000 && (serviced_query_udp_size(sq, serviced_query_UDP_EDNS_FRAG) < serviced_query_udp_size(sq, serviced_query_UDP_EDNS))) { - /* fallback to 1480/1280 */ + /* fallback to 1472/1232 */ sq->status = serviced_query_UDP_EDNS_FRAG; - log_name_addr(VERB_ALGO, "try edns1xx0", sq->qbuf+10, + log_name_addr(VERB_ALGO, "try edns1xx2", sq->qbuf+10, &sq->addr, sq->addrlen); if(!serviced_udp_send(sq, c->buffer)) { serviced_callbacks(sq, NETEVENT_CLOSED, c, rep); @@ -3426,7 +3501,8 @@ outnet_serviced_query(struct outside_net char* tls_auth_name, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, size_t zonelen, struct module_qstate* qstate, comm_point_callback_type* callback, void* callback_arg, - sldns_buffer* buff, struct module_env* env, int* was_ratelimited) + sldns_buffer* buff, struct module_env* env, int* was_ratelimited, + int* ratelimit_incremented) { struct serviced_query* sq; struct service_callback* cb; @@ -3498,6 +3574,7 @@ outnet_serviced_query(struct outside_net "delegation point", zone, LDNS_RR_TYPE_NS, LDNS_RR_CLASS_IN); } + *ratelimit_incremented = 1; } /* make new serviced query entry */ sq = serviced_create(outnet, buff, dnssec, want_dnssec, nocaps, @@ -3579,13 +3656,16 @@ fd_for_dest(struct outside_network* outn { struct sockaddr_storage* addr; socklen_t addrlen; - int i, try, pnum, dscp; + int i, try, dscp; struct port_if* pif; /* create fd */ dscp = outnet->ip_dscp; for(try = 0; try<1000; try++) { int port = 0; +#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION + int reused = 0; +#endif int freebind = 0; int noproto = 0; int inuse = 0; @@ -3614,16 +3694,18 @@ fd_for_dest(struct outside_network* outn addr = &pif->addr; addrlen = pif->addrlen; #ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION - pnum = ub_random_max(outnet->rnd, pif->avail_total); - if(pnum < pif->inuse) { - /* port already open */ - port = pif->out[pnum]->number; - } else { - /* unused ports in start part of array */ - port = pif->avail_ports[pnum - pif->inuse]; + if(!shared_ports_fetch_random(outnet->shared_ports, + pif->shpif, outnet->rnd, 0, pif->inuse, + &port, &reused)) { + /* try again, perhaps another interface. */ + continue; + } + if(reused) { + log_assert(port < pif->inuse); + port = pif->out[port]->number; } #else - pnum = port = 0; + port = 0; #endif if(addr_is_ip6(to_addr, to_addrlen)) { struct sockaddr_in6 sa = *(struct sockaddr_in6*)addr; @@ -3638,6 +3720,14 @@ fd_for_dest(struct outside_network* outn (struct sockaddr*)addr, addrlen, 1, &inuse, &noproto, 0, 0, 0, NULL, 0, freebind, 0, dscp); } +#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION + if(!reused) { + /* Return the port to the pool, since the caller does + * not keep track of it, also have done fd, and bind. */ + shared_ports_return_port(outnet->shared_ports, + pif->shpif, port); + } +#endif if(fd != -1) { return fd; } @@ -3690,7 +3780,33 @@ setup_comm_ssl(struct comm_point* cp, st (void)SSL_set_tlsext_host_name(cp->ssl, host); } #endif -#ifdef HAVE_SSL_SET1_HOST +#ifdef HAVE_SSL_SET1_DNSNAME + if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) { + /* because we set SSL_VERIFY_PEER, in netevent in + * ssl_handshake, it'll check if the certificate + * verification has succeeded */ + /* SSL_VERIFY_PEER is set on the sslctx */ + /* and the certificates to verify with are loaded into + * it with SSL_load_verify_locations or + * SSL_CTX_set_default_verify_paths */ + /* setting the hostname makes openssl verify the + * host name in the x509 certificate in the + * SSL connection*/ + struct sockaddr_storage tmpaddr; + socklen_t tmpaddrlen = (socklen_t)sizeof(tmpaddr); + if(ipstrtoaddr(host, UNBOUND_DNS_PORT, &tmpaddr, &tmpaddrlen)) { + if(!SSL_set1_ipaddr(cp->ssl, host)) { + log_err("SSL_set1_ipaddr failed"); + return 0; + } + } else { + if(!SSL_set1_dnsname(cp->ssl, host)) { + log_err("SSL_set1_dnsname failed"); + return 0; + } + } + } +#elif defined(HAVE_SSL_SET1_HOST) if((SSL_CTX_get_verify_mode(outnet->sslctx)&SSL_VERIFY_PEER)) { /* because we set SSL_VERIFY_PEER, in netevent in * ssl_handshake, it'll check if the certificate @@ -3819,7 +3935,8 @@ outnet_comm_point_for_http(struct outsid /* outnet_tcp_connect has closed fd on error for us */ return 0; } - cp = comm_point_create_http_out(outnet->base, 65552, cb, cb_arg, + cp = comm_point_create_http_out(outnet->base, + sldns_buffer_capacity(outnet->udp_buff), cb, cb_arg, outnet->udp_buff); if(!cp) { log_err("malloc failure"); @@ -3868,11 +3985,7 @@ if_get_mem(struct port_if* pif) { size_t s; int i; - s = sizeof(*pif) + -#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION - sizeof(int)*pif->avail_total + -#endif - sizeof(struct port_comm*)*pif->maxout; + s = sizeof(*pif) + sizeof(struct port_comm*)*pif->maxout; for(i=0; iinuse; i++) s += sizeof(*pif->out[i]) + comm_point_get_mem(pif->out[i]->cp); @@ -3960,3 +4073,250 @@ serviced_get_mem(struct serviced_query* return s; } +#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION +/** Setup shared port interface */ +static int shared_ports_setup_if(struct shared_ports_if* shpif, char* str, + int* availports, int numavailports) +{ + shpif->avail_ports = (int*)memdup(availports, + (size_t)numavailports*sizeof(int)); + if(!shpif->avail_ports) + return 0; + shpif->avail_total = numavailports; + shpif->inuse = 0; + shpif->pfxlen = 0; + if(!ipstrtoaddr(str, UNBOUND_DNS_PORT, &shpif->addr, &shpif->addrlen) && + !netblockstrtoaddr(str, UNBOUND_DNS_PORT, &shpif->addr, + &shpif->addrlen, &shpif->pfxlen)) + return 0; + return 1; +} +#endif + +#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION +/** Allocate shared ports interfaces */ +static int shared_ports_alloc_ifs(struct shared_ports* shp, char** ifs, + int num_ifs, int do_ip4, int do_ip6, int* availports, + int numavailports) +{ +#ifndef INET6 + do_ip6 = 0; +#endif + calc_num46(ifs, num_ifs, do_ip4, do_ip6, + &shp->num_ip4, &shp->num_ip6); + if(shp->num_ip4 != 0) { + if(!(shp->ip4_ifs = (struct shared_ports_if*)calloc( + (size_t)shp->num_ip4, + sizeof(struct shared_ports_if)))) + return 0; + } + if(shp->num_ip6 != 0) { + if(!(shp->ip6_ifs = (struct shared_ports_if*)calloc( + (size_t)shp->num_ip6, + sizeof(struct shared_ports_if)))) + return 0; + } + if(num_ifs == 0) { + if(do_ip4 && !shared_ports_setup_if(&shp->ip4_ifs[0], + "0.0.0.0", availports, numavailports)) + return 0; + if(do_ip6 && !shared_ports_setup_if(&shp->ip6_ifs[0], + "::", availports, numavailports)) + return 0; + } else { + size_t done_4 = 0, done_6 = 0; + int i; + for(i=0; inum_ip6) { + if(!shared_ports_setup_if(&shp->ip6_ifs[done_6], + ifs[i], availports, numavailports)) + return 0; + done_6++; + } + if(!str_is_ip6(ifs[i]) && do_ip4 && + (int)done_4 < shp->num_ip4) { + if(!shared_ports_setup_if(&shp->ip4_ifs[done_4], + ifs[i], availports, numavailports)) + return 0; + done_4++; + } + } + } + return 1; +} +#endif + +struct shared_ports* shared_ports_create(char** ifs, int num_ifs, int do_ip4, + int do_ip6, int* availports, int numavailports) +{ + struct shared_ports* shp = calloc(1, sizeof(*shp)); + if(!shp) { + log_err("malloc failed"); + return NULL; + } + lock_basic_init(&shp->lock); + lock_protect(&shp->lock, &shp->ip4_ifs, sizeof(shp->ip4_ifs)); + lock_protect(&shp->lock, &shp->num_ip4, sizeof(shp->num_ip4)); + lock_protect(&shp->lock, &shp->ip6_ifs, sizeof(shp->ip6_ifs)); + lock_protect(&shp->lock, &shp->num_ip6, sizeof(shp->num_ip6)); + +#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION + /* Allocate interfaces */ + lock_basic_lock(&shp->lock); + if(!shared_ports_alloc_ifs(shp, ifs, num_ifs, do_ip4, do_ip6, + availports, numavailports)) { + log_err("malloc failed"); + shared_ports_delete(shp); + return NULL; + } + lock_basic_unlock(&shp->lock); +#else + (void)ifs; (void)num_ifs; (void)do_ip4; (void)do_ip6; + (void)availports; (void)numavailports; +#endif + return shp; +} + +#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION +/** Delete shared ports interface structure */ +static void shared_ports_if_delete(struct shared_ports_if* shpif) +{ + if(!shpif) + return; + free(shpif->avail_ports); +} +#endif + +void shared_ports_delete(struct shared_ports* shp) +{ +#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION + int i; +#endif + if(!shp) + return; + lock_basic_destroy(&shp->lock); +#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION + for(i=0; inum_ip4; i++) { + shared_ports_if_delete(&shp->ip4_ifs[i]); + } + free(shp->ip4_ifs); + for(i=0; inum_ip6; i++) { + shared_ports_if_delete(&shp->ip6_ifs[i]); + } + free(shp->ip6_ifs); +#endif + free(shp); +} + +struct shared_ports_if* shared_ports_find_if(struct shared_ports* shp, + struct sockaddr_storage* addr, socklen_t addrlen, int pfxlen) +{ +#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION + struct shared_ports_if* ret, *ifs = NULL; + int i, num_ifs = 0; + lock_basic_lock(&shp->lock); + if(addr_is_ip6(addr, addrlen)) { + ifs = shp->ip6_ifs; + num_ifs = shp->num_ip6; + } else { + ifs = shp->ip4_ifs; + num_ifs = shp->num_ip4; + } + for(i=0; ilock); + return ret; + } + } + lock_basic_unlock(&shp->lock); + return NULL; +#else + (void)shp; (void)addr; (void)addrlen; (void)pfxlen; + return NULL; +#endif +} + +int shared_ports_fetch_random(struct shared_ports* shp, + struct shared_ports_if* shpif, struct ub_randstate* rnd, + int udp_connect, int reusenum, int* port, int* reused) +{ +#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION + int portno = 0, my_port = 0; + if(!shpif) + return 0; +# ifdef THREADS_DISABLED + (void)shp; +# endif + lock_basic_lock(&shp->lock); + if(udp_connect) { + /* if we connect() we cannot reuse fds for a port. */ + if(shpif->inuse >= shpif->avail_total) { + lock_basic_unlock(&shp->lock); + return 0; + } + my_port = ub_random_max(rnd, + shpif->avail_total - shpif->inuse); + } else { + /* select from free ports and open ports on this thread. */ + if(shpif->inuse >= shpif->avail_total) { + lock_basic_unlock(&shp->lock); + if(reusenum == 0) { + return 0; + } + my_port = ub_random_max(rnd, reusenum); + *port = my_port; + *reused = 1; + return 1; + } + my_port = ub_random_max(rnd, shpif->avail_total - shpif->inuse + + reusenum); + if(my_port < reusenum) { + /* port already open */ + lock_basic_unlock(&shp->lock); + *port = my_port; + *reused = 1; + return 1; + } + my_port -= reusenum; + } + log_assert(shpif->inuse < shpif->avail_total); + log_assert(my_port >= 0 && my_port < shpif->avail_total); + portno = shpif->avail_ports[my_port]; + shpif->avail_ports[my_port] = + shpif->avail_ports[shpif->avail_total-shpif->inuse-1]; + shpif->inuse++; + lock_basic_unlock(&shp->lock); + *port = portno; + *reused = 0; + return 1; +#else + (void)shp; (void)shpif; (void)rnd; (void)udp_connect; + (void)reusenum; + *port = 0; + *reused = 0; + return 1; +#endif +} + +void shared_ports_return_port(struct shared_ports* shp, + struct shared_ports_if* shpif, int port) +{ +#ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION + if(!shpif) + return; +# ifdef THREADS_DISABLED + (void)shp; +# endif + lock_basic_lock(&shp->lock); + log_assert(shpif->inuse > 0); + shpif->avail_ports[shpif->avail_total - shpif->inuse] = port; + shpif->inuse--; + lock_basic_unlock(&shp->lock); +#else + (void)shp; (void)shpif; (void)port; +#endif +} Index: sbin/unwind/libunbound/services/outside_network.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/services/outside_network.h,v diff -u -p -r1.11 outside_network.h --- sbin/unwind/libunbound/services/outside_network.h 14 Sep 2025 15:16:53 -0000 1.11 +++ sbin/unwind/libunbound/services/outside_network.h 21 Sep 2026 16:28:25 -0000 @@ -48,6 +48,10 @@ #include "util/regional.h" #include "util/netevent.h" #include "dnstap/dnstap_config.h" +#ifdef __QNX__ +/* For struct timeval */ +#include +#endif /* __QNX__ */ struct pending; struct pending_timeout; struct ub_randstate; @@ -66,6 +70,8 @@ struct module_env; struct module_qstate; struct query_info; struct config_file; +struct shared_ports; +struct shared_ports_if; /** * Send queries to outside servers and wait for answers from servers. @@ -115,6 +121,9 @@ struct outside_network { int udp_connect; /** number of udp packets sent. */ size_t num_udp_outgoing; + /** the shared ports structure, with random ports numbers. + * This is a reference to the member in the daemon structure. */ + struct shared_ports* shared_ports; /** array of outgoing IP4 interfaces */ struct port_if* ip4_ifs; @@ -207,11 +216,8 @@ struct port_if { int pfxlen; #ifndef DISABLE_EXPLICIT_PORT_RANDOMISATION - /** the available ports array. These are unused. - * Only the first total-inuse part is filled. */ - int* avail_ports; - /** the total number of available ports (size of the array) */ - int avail_total; + /** the shared port numbers for this interface. */ + struct shared_ports_if* shpif; #endif /** array of the commpoints currently in use. @@ -242,6 +248,42 @@ struct port_comm { }; /** + * Shared ports, the list of ports shared across threads + */ +struct shared_ports { + /** mutex on the ports */ + lock_basic_type lock; + /** array of IP4 interfaces */ + struct shared_ports_if* ip4_ifs; + /** number of outgoing IP4 interfaces */ + int num_ip4; + /** array of IP6 interfaces */ + struct shared_ports_if* ip6_ifs; + /** number of outgoing IP6 interfaces */ + int num_ip6; +}; + +/** + * Shared ports for an interface. + */ +struct shared_ports_if { + /** address ready to allocate new socket (except port no). */ + struct sockaddr_storage addr; + /** length of addr field */ + socklen_t addrlen; + /** if a netblock, the prefix */ + int pfxlen; + + /** the available ports array. These are unused. + * Only the first total-inuse part is filled. */ + int* avail_ports; + /** the total number of available ports (size of the array) */ + int avail_total; + /** the number in use. */ + int inuse; +}; + +/** * Reuse TCP connection, still open can be used again. */ struct reuse_tcp { @@ -260,6 +302,9 @@ struct reuse_tcp { socklen_t addrlen; /** also key for tcp_reuse tree, if ssl is used */ int is_ssl; + /** If is_ssl is enabled, tls_auth_name is part of the key for + * tcp_reuse tree. If the string is NULL, it without a tls_auth_name */ + char* tls_auth_name; /** lru chain, so that the oldest can be removed to get a new * connection when all are in (re)use. oldest is last in list. * The lru only contains empty connections waiting for reuse, @@ -412,7 +457,7 @@ struct waiting_tcp { void* cb_arg; /** if it uses ssl upstream */ int ssl_upstream; - /** ref to the tls_auth_name from the serviced_query */ + /** owned copy of the tls_auth_name (malloced) */ char* tls_auth_name; /** the packet was involved in an error, to stop looping errors */ int error_count; @@ -493,7 +538,7 @@ struct serviced_query { serviced_query_UDP_EDNS_fallback, /** probe to test TCP noEDNS0 (EDNS gives FORMERRorNOTIMP) */ serviced_query_TCP_EDNS_fallback, - /** send UDP query with EDNS1480 (or 1280) */ + /** send UDP query with EDNS1472 (or 1232) */ serviced_query_UDP_EDNS_FRAG } /** variable with current status */ @@ -544,8 +589,6 @@ struct serviced_query { * @param infra: pointer to infra cached used for serviced queries. * @param rnd: stored to create random numbers for serviced queries. * @param use_caps_for_id: enable to use 0x20 bits to encode id randomness. - * @param availports: array of available ports. - * @param numavailports: number of available ports in array. * @param unwanted_threshold: when to take defensive action. * @param unwanted_action: the action to take. * @param unwanted_param: user parameter to action. @@ -560,17 +603,18 @@ struct serviced_query { * @param max_reuse_tcp_queries: max number of queries on a reuse connection. * @param tcp_reuse_timeout: timeout for REUSE entries in milliseconds. * @param tcp_auth_query_timeout: timeout in milliseconds for TCP queries to auth servers. + * @param shared_ports: the shared_ports structure. * @return: the new structure (with no pending answers) or NULL on error. */ struct outside_network* outside_network_create(struct comm_base* base, size_t bufsize, size_t num_ports, char** ifs, int num_ifs, int do_ip4, int do_ip6, size_t num_tcp, int dscp, struct infra_cache* infra, - struct ub_randstate* rnd, int use_caps_for_id, int* availports, - int numavailports, size_t unwanted_threshold, int tcp_mss, + struct ub_randstate* rnd, int use_caps_for_id, + size_t unwanted_threshold, int tcp_mss, void (*unwanted_action)(void*), void* unwanted_param, int do_udp, void* sslctx, int delayclose, int tls_use_sni, struct dt_env *dtenv, int udp_connect, int max_reuse_tcp_queries, int tcp_reuse_timeout, - int tcp_auth_query_timeout); + int tcp_auth_query_timeout, struct shared_ports* shared_ports); /** * Delete outside_network structure. @@ -653,6 +697,8 @@ void pending_delete(struct outside_netwo * @param env: the module environment. * @param was_ratelimited: it will signal back if the query failed to pass the * ratelimit check. + * @param ratelimit_incremented: set to true if the ratelimit counter + * was increased. * @return 0 on error, or pointer to serviced query that is used to answer * this serviced query may be shared with other callbacks as well. */ @@ -662,7 +708,8 @@ struct serviced_query* outnet_serviced_q char* tls_auth_name, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, size_t zonelen, struct module_qstate* qstate, comm_point_callback_type* callback, void* callback_arg, - struct sldns_buffer* buff, struct module_env* env, int* was_ratelimited); + struct sldns_buffer* buff, struct module_env* env, int* was_ratelimited, + int* ratelimit_incremented); /** * Remove service query callback. @@ -811,6 +858,54 @@ struct comm_point* outnet_comm_point_for /** connect tcp connection to addr, 0 on failure */ int outnet_tcp_connect(int s, struct sockaddr_storage* addr, socklen_t addrlen); + +/** + * Create new shared ports structure. + * @param ifs: interface names (or NULL for default interface). + * These interfaces must be able to access all authoritative servers. + * @param num_ifs: number of names in array ifs. + * @param do_ip4: service IP4. + * @param do_ip6: service IP6. + * @param availports: array of available ports. + * @param numavailports: number of available ports in array. + * @return new, or NULL on failure. + */ +struct shared_ports* shared_ports_create(char** ifs, int num_ifs, int do_ip4, + int do_ip6, int* availports, int numavailports); + +/** + * Delete shared ports structure. + * @param shp: shared ports structure. + */ +void shared_ports_delete(struct shared_ports* shp); + +/** Find interface in shared ports. */ +struct shared_ports_if* shared_ports_find_if(struct shared_ports* shp, + struct sockaddr_storage* addr, socklen_t addrlen, int pfxlen); + +/** + * Get a shared port from the list of random ports. + * @param shp: shared ports structure. + * @param shpif: the shared ports interface. + * @param rnd: used to make random numbers. + * @param udp_connect: set to true if no reuse is possible. + * @param reusenum: number of ports that can be reused (already open). + * @param port: the port number is returned. + * @param reused: if the port numer is reused, returned. + * @return false on failure. That can mean no more free ports to use. + */ +int shared_ports_fetch_random(struct shared_ports* shp, + struct shared_ports_if* shpif, struct ub_randstate* rnd, + int udp_connect, int reusenum, int* port, int* reused); + +/** + * Return a shared port to the list of random ports. + * @param shp: shared ports structure. + * @param shpif: the shared ports interface. + * @param port: port number to return to be used again. + */ +void shared_ports_return_port(struct shared_ports* shp, + struct shared_ports_if* shpif, int port); /** callback for incoming udp answers from the network */ int outnet_udp_cb(struct comm_point* c, void* arg, int error, Index: sbin/unwind/libunbound/services/rpz.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/services/rpz.c,v diff -u -p -r1.16 rpz.c --- sbin/unwind/libunbound/services/rpz.c 29 Sep 2025 14:53:38 -0000 1.16 +++ sbin/unwind/libunbound/services/rpz.c 21 Sep 2026 16:28:25 -0000 @@ -153,6 +153,7 @@ rpz_type_ignored(uint16_t rr_type) case LDNS_RR_TYPE_SOA: case LDNS_RR_TYPE_NS: case LDNS_RR_TYPE_DNAME: + case LDNS_RR_TYPE_ZONEMD: /* all DNSSEC-related RRs must be ignored */ case LDNS_RR_TYPE_DNSKEY: case LDNS_RR_TYPE_DS: @@ -720,13 +721,22 @@ rpz_insert_local_zones_trigger(struct lo char* rrstr = sldns_wire2str_rr(rr, rr_len); if(rrstr == NULL) { log_err("malloc error while inserting rpz nsdname trigger"); - free(dname); + if(!newzone) + free(dname); lock_rw_unlock(&lz->lock); return; } lock_rw_wrlock(&z->lock); - local_zone_enter_rr(z, dname, dnamelen, dnamelabs, rrtype, - rrclass, ttl, rdata, rdata_len, rrstr); + if(!local_zone_enter_rr(z, dname, dnamelen, dnamelabs, rrtype, + rrclass, ttl, rdata, rdata_len, rrstr)) { + log_err("rpz: could not enter local-data: %s", rrstr); + if(!newzone) + free(dname); + lock_rw_unlock(&z->lock); + lock_rw_unlock(&lz->lock); + free(rrstr); + return; + } lock_rw_unlock(&z->lock); free(rrstr); } @@ -804,8 +814,9 @@ rpz_insert_nsdname_trigger(struct rpz* r uint8_t* dname_stripped = NULL; size_t dnamelen_stripped = 0; - rpz_strip_nsdname_suffix(dname, dnamelen, &dname_stripped, - &dnamelen_stripped); + if(!rpz_strip_nsdname_suffix(dname, dnamelen, &dname_stripped, + &dnamelen_stripped)) + return; if(a == RPZ_INVALID_ACTION) { verbose(VERB_ALGO, "rpz: skipping invalid action"); free(dname_stripped); @@ -903,8 +914,8 @@ rpz_report_rrset_error(const char* msg, /* from localzone.c; difference is we don't have a dname */ static struct local_rrset* -rpz_clientip_new_rrset(struct regional* region, - struct clientip_synthesized_rr* raddr, uint16_t rrtype, uint16_t rrclass) +rpz_clientip_new_rrset(struct regional* region, uint16_t rrtype, + uint16_t rrclass) { struct packed_rrset_data* pd; struct local_rrset* rrset = (struct local_rrset*) @@ -913,8 +924,6 @@ rpz_clientip_new_rrset(struct regional* log_err("out of memory"); return NULL; } - rrset->next = raddr->data; - raddr->data = rrset; rrset->rrset = (struct ub_packed_rrset_key*) regional_alloc_zero(region, sizeof(*rrset->rrset)); if(rrset->rrset == NULL) { @@ -953,12 +962,18 @@ rpz_clientip_enter_rr(struct regional* r return 0; } - rrset = rpz_clientip_new_rrset(region, raddr, rrtype, rrclass); - if(raddr->data == NULL) { + rrset = rpz_clientip_new_rrset(region, rrtype, rrclass); + if(rrset == NULL) { return 0; } - return rrset_insert_rr(region, rrset->rrset->entry.data, rdata, rdata_len, ttl, ""); + if(!rrset_insert_rr(region, rrset->rrset->entry.data, rdata, rdata_len, ttl, "")) + return 0; + + /* Link in now that the allocations have succeeded. */ + rrset->next = raddr->data; + raddr->data = rrset; + return 1; } static int @@ -981,7 +996,6 @@ rpz_clientip_insert_trigger_rr(struct cl lock_rw_wrlock(&node->lock); lock_rw_unlock(&set->lock); - node->action = a; if(a == RPZ_LOCAL_DATA_ACTION) { if(!rpz_clientip_enter_rr(set->region, node, rrtype, rrclass, ttl, rdata, rdata_len)) { @@ -991,6 +1005,7 @@ rpz_clientip_insert_trigger_rr(struct cl } } + node->action = a; lock_rw_unlock(&node->lock); @@ -1976,8 +1991,9 @@ rpz_synthesize_nodata(struct rpz* ATTR_U 0, /* total */ sec_status_insecure, LDNS_EDE_NONE); - if(msg->rep) - msg->rep->authoritative = 1; + if(!msg->rep) + return NULL; + msg->rep->authoritative = 1; if(!rpz_add_soa(msg->rep, ms, az)) return NULL; return msg; @@ -2007,8 +2023,9 @@ rpz_synthesize_nxdomain(struct rpz* r, s 0, /* total */ sec_status_insecure, LDNS_EDE_NONE); - if(msg->rep) - msg->rep->authoritative = 1; + if(!msg->rep) + return NULL; + msg->rep->authoritative = 1; if(!rpz_add_soa(msg->rep, ms, az)) return NULL; return msg; @@ -2468,6 +2485,7 @@ rpz_callback_from_iterator_module(struct { struct auth_zones* az; struct auth_zone* a; + struct dns_msg* ret = NULL; struct clientip_synthesized_rr* raddr = NULL; struct rpz* r = NULL; struct local_zone* z = NULL; @@ -2511,13 +2529,11 @@ rpz_callback_from_iterator_module(struct z = rpz_delegation_point_zone_lookup(is->dp, r->nsdname_zones, is->qchase.qclass, &match); if(z != NULL) { - lock_rw_unlock(&a->lock); break; } raddr = rpz_delegation_point_ipbased_trigger_lookup(r, is); if(raddr != NULL) { - lock_rw_unlock(&a->lock); break; } lock_rw_unlock(&a->lock); @@ -2532,9 +2548,12 @@ rpz_callback_from_iterator_module(struct if(z) { lock_rw_unlock(&z->lock); } - return rpz_apply_nsip_trigger(ms, &is->qchase, r, raddr, a); + ret = rpz_apply_nsip_trigger(ms, &is->qchase, r, raddr, a); + } else { + ret = rpz_apply_nsdname_trigger(ms, &is->qchase, r, z, &match, a); } - return rpz_apply_nsdname_trigger(ms, &is->qchase, r, z, &match, a); + lock_rw_unlock(&a->lock); + return ret; } struct dns_msg* rpz_callback_from_iterator_cname(struct module_qstate* ms, Index: sbin/unwind/libunbound/services/cache/dns.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/services/cache/dns.c,v diff -u -p -r1.16 dns.c --- sbin/unwind/libunbound/services/cache/dns.c 14 Sep 2025 15:16:53 -0000 1.16 +++ sbin/unwind/libunbound/services/cache/dns.c 21 Sep 2026 16:28:25 -0000 @@ -43,6 +43,7 @@ #include "iterator/iter_utils.h" #include "validator/val_nsec.h" #include "validator/val_utils.h" +#include "iterator/iter_utils.h" #include "services/cache/dns.h" #include "services/cache/rrset.h" #include "util/data/msgparse.h" @@ -60,10 +61,10 @@ * @param rep: contains list of rrsets to store. * @param now: current time. * @param leeway: during prefetch how much leeway to update TTLs. - * This makes rrsets (other than type NS) timeout sooner so they get - * updated with a new full TTL. - * Type NS does not get this, because it must not be refreshed from the - * child domain, but keep counting down properly. + * This makes rrsets expire sooner so they get updated with a new full + * TTL. + * Child side type NS does get this but TTL checks are done using the time + * the query was created rather than the time the answer was received. * @param pside: if from parentside discovered NS, so that its NS is okay * in a prefetch situation to be updated (without becoming sticky). * @param qrep: update rrsets here if cache is better @@ -100,11 +101,20 @@ store_rrsets(struct module_env* env, str rep->ref[i].id != rep->ref[i].key->id) ck = NULL; else ck = packed_rrset_copy_region( - rep->ref[i].key, region, now); + rep->ref[i].key, region, + ((ntohs(rep->ref[i].key->rk.type)== + LDNS_RR_TYPE_NS && !pside)?qstarttime:now)); lock_rw_unlock(&rep->ref[i].key->entry.lock); if(ck) { /* use cached copy if memory allows */ qrep->rrsets[i] = ck; + ttl = ((struct packed_rrset_data*) + ck->entry.data)->ttl; + if(ttl < qrep->ttl) { + qrep->ttl = ttl; + qrep->prefetch_ttl = PREFETCH_TTL_CALC(qrep->ttl); + qrep->serve_expired_ttl = qrep->ttl + SERVE_EXPIRED_TTL; + } } } /* no break: also copy key item */ @@ -122,8 +132,8 @@ store_rrsets(struct module_env* env, str rep->ref[i].id == rep->ref[i].key->id) { ttl = ((struct packed_rrset_data*) rep->rrsets[i]->entry.data)->ttl; - if(ttl < min_ttl) min_ttl = ttl; - } + if(ttl < min_ttl) min_ttl = ttl; + } lock_rw_unlock(&rep->ref[i].key->entry.lock); } } @@ -169,10 +179,12 @@ dns_cache_store_msg(struct module_env* e /* there was a reply_info_sortref(rep) here but it seems to be * unnecessary, because the cache gets locked per rrset. */ - reply_info_set_ttls(rep, *env->now); + if((flags & DNSCACHE_STORE_EXPIRED_MSG_CACHEDB)) { + reply_info_absolute_ttls(rep, *env->now, *env->now - ttl); + } else reply_info_set_ttls(rep, *env->now); store_rrsets(env, rep, *env->now, leeway, pside, qrep, region, qstarttime); - if(ttl == 0 && !(flags & DNSCACHE_STORE_ZEROTTL)) { + if(ttl == 0) { /* we do not store the message, but we did store the RRs, * which could be useful for delegation information */ verbose(VERB_ALGO, "TTL 0: dropped msg from cache"); @@ -221,8 +233,15 @@ find_closest_of_type(struct module_env* /* snip off front part of qname until the type is found */ while(qnamelen > 0) { - if((rrset = rrset_cache_lookup(env->rrset_cache, qname, - qnamelen, searchtype, qclass, 0, now, 0))) { + rrset = rrset_cache_lookup(env->rrset_cache, qname, + qnamelen, searchtype, qclass, 0, now, 0); + if(!rrset && searchtype == LDNS_RR_TYPE_DNAME) + /* If not found, for type DNAME, try 0TTL stored, + * for its grace period. */ + rrset = rrset_cache_lookup(env->rrset_cache, qname, + qnamelen, searchtype, qclass, + PACKED_RRSET_UPSTREAM_0TTL, now, 0); + if(rrset) { uint8_t* origqname = qname; size_t origqnamelen = qnamelen; if(!noexpiredabove) @@ -259,6 +278,8 @@ find_closest_of_type(struct module_env* /* snip off front label */ lablen = *qname; + if(lablen == 0) + break; qname += lablen + 1; qnamelen -= lablen + 1; } @@ -272,8 +293,10 @@ addr_to_additional(struct ub_packed_rrse { if((msg->rep->rrsets[msg->rep->rrset_count] = packed_rrset_copy_region(rrset, region, now))) { + struct packed_rrset_data* d = rrset->entry.data; msg->rep->ar_numrrsets++; msg->rep->rrset_count++; + UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl); } } @@ -456,8 +479,10 @@ find_add_ds(struct module_env* env, stru /* add it to auth section. This is the second rrset. */ if((msg->rep->rrsets[msg->rep->rrset_count] = packed_rrset_copy_region(rrset, region, now))) { + struct packed_rrset_data* d = rrset->entry.data; msg->rep->ns_numrrsets++; msg->rep->rrset_count++; + UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl); } lock_rw_unlock(&rrset->entry.lock); } @@ -487,6 +512,8 @@ dns_msg_create(uint8_t* qname, size_t qn return NULL; /* integer overflow protection */ msg->rep->flags = BIT_QR; /* with QR, no AA */ msg->rep->qdcount = 1; + msg->rep->ttl = MAX_TTL; /* will be updated (brought down) while we add + * rrsets to the message */ msg->rep->reason_bogus = LDNS_EDE_NONE; msg->rep->rrsets = (struct ub_packed_rrset_key**) regional_alloc(region, @@ -497,24 +524,28 @@ dns_msg_create(uint8_t* qname, size_t qn } int -dns_msg_authadd(struct dns_msg* msg, struct regional* region, +dns_msg_authadd(struct dns_msg* msg, struct regional* region, struct ub_packed_rrset_key* rrset, time_t now) { - if(!(msg->rep->rrsets[msg->rep->rrset_count++] = + struct packed_rrset_data* d = rrset->entry.data; + if(!(msg->rep->rrsets[msg->rep->rrset_count++] = packed_rrset_copy_region(rrset, region, now))) return 0; msg->rep->ns_numrrsets++; + UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl); return 1; } int -dns_msg_ansadd(struct dns_msg* msg, struct regional* region, +dns_msg_ansadd(struct dns_msg* msg, struct regional* region, struct ub_packed_rrset_key* rrset, time_t now) { - if(!(msg->rep->rrsets[msg->rep->rrset_count++] = + struct packed_rrset_data* d = rrset->entry.data; + if(!(msg->rep->rrsets[msg->rep->rrset_count++] = packed_rrset_copy_region(rrset, region, now))) return 0; msg->rep->an_numrrsets++; + UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl); return 1; } @@ -556,8 +587,12 @@ dns_cache_find_delegation(struct module_ return NULL; } } - if(!delegpt_rrset_add_ns(dp, region, nskey, 0)) + if(!delegpt_rrset_add_ns(dp, region, nskey, 0, + deleg_port_number(env))) { + lock_rw_unlock(&nskey->entry.lock); log_err("find_delegation: addns out of memory"); + return NULL; + } lock_rw_unlock(&nskey->entry.lock); /* first unlock before next lookup*/ /* find and add DS/NSEC (if any) */ if(msg) @@ -585,6 +620,7 @@ gen_dns_msg(struct regional* region, str sizeof(struct reply_info) - sizeof(struct rrset_ref)); if(!msg->rep) return NULL; + msg->rep->ttl = MAX_TTL; msg->rep->reason_bogus = LDNS_EDE_NONE; msg->rep->reason_bogus_str = NULL; if(num > RR_COUNT_MAX) @@ -606,13 +642,13 @@ tomsg(struct module_env* env, struct que size_t i; int is_expired = 0; time_t now_control = now; - if(now > r->ttl) { + if(TTL_IS_EXPIRED(r->ttl, now)) { /* Check if we are allowed to serve expired */ if(!allow_expired || !reply_info_can_answer_expired(r, now)) return NULL; - /* Change the current time so we can pass the below TTL checks when - * serving expired data. */ - now_control = r->ttl - env->cfg->serve_expired_reply_ttl; + /* Change the current time so we can pass the below TTL checks + * when serving expired data. */ + now_control = 0; is_expired = 1; } @@ -620,15 +656,6 @@ tomsg(struct module_env* env, struct que if(!msg) return NULL; msg->rep->flags = r->flags; msg->rep->qdcount = r->qdcount; - msg->rep->ttl = is_expired - ?SERVE_EXPIRED_REPLY_TTL - :r->ttl - now; - if(r->prefetch_ttl > now) - msg->rep->prefetch_ttl = r->prefetch_ttl - now; - else - msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl); - msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL; - msg->rep->serve_expired_norec_ttl = 0; msg->rep->security = r->security; msg->rep->an_numrrsets = r->an_numrrsets; msg->rep->ns_numrrsets = r->ns_numrrsets; @@ -650,19 +677,36 @@ tomsg(struct module_env* env, struct que rrset_array_unlock(r->ref, r->rrset_count); return NULL; } - if(r->security == sec_status_secure && !reply_all_rrsets_secure(r)) { + if(r->security == sec_status_secure && !reply_an_ns_rrsets_secure(r)) { /* message rrsets have changed status, revalidate */ rrset_array_unlock(r->ref, r->rrset_count); return NULL; } for(i=0; irep->rrset_count; i++) { + struct packed_rrset_data* d; msg->rep->rrsets[i] = packed_rrset_copy_region(r->rrsets[i], region, now); if(!msg->rep->rrsets[i]) { rrset_array_unlock(r->ref, r->rrset_count); return NULL; } + d = msg->rep->rrsets[i]->entry.data; + UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl); + } + if(msg->rep->rrset_count < 1) { + msg->rep->ttl = is_expired + ?SERVE_EXPIRED_REPLY_TTL + :r->ttl - now; + if(r->prefetch_ttl > now) + msg->rep->prefetch_ttl = r->prefetch_ttl - now; + else + msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl); + } else { + /* msg->rep->ttl has been updated through the RRSets above */ + msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl); } + msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL; + msg->rep->serve_expired_norec_ttl = 0; if(env) rrset_array_unlock_touch(env->rrset_cache, scratch, r->ref, r->rrset_count); @@ -675,10 +719,16 @@ struct dns_msg* dns_msg_deepcopy_region(struct dns_msg* origin, struct regional* region) { size_t i; + struct ub_packed_rrset_key** saved_rrsets; struct dns_msg* res = NULL; + size_t rep_alloc_size = sizeof(struct reply_info) + - sizeof(struct rrset_ref); /* this is the size of res->rep + allocated in gen_dns_msg() */ res = gen_dns_msg(region, &origin->qinfo, origin->rep->rrset_count); if(!res) return NULL; - *res->rep = *origin->rep; + saved_rrsets = res->rep->rrsets; /* save rrsets alloc by gen_dns_msg */ + memcpy(res->rep, origin->rep, rep_alloc_size); + res->rep->rrsets = saved_rrsets; if(origin->rep->reason_bogus_str) { res->rep->reason_bogus_str = regional_strdup(region, origin->rep->reason_bogus_str); @@ -701,7 +751,7 @@ rrset_msg(struct ub_packed_rrset_key* rr struct dns_msg* msg; struct packed_rrset_data* d = (struct packed_rrset_data*) rrset->entry.data; - if(now > d->ttl) + if(TTL_IS_EXPIRED(d->ttl, now)) return NULL; msg = gen_dns_msg(region, q, 1); /* only the CNAME (or other) RRset */ if(!msg) @@ -736,8 +786,20 @@ synth_dname_msg(struct ub_packed_rrset_k rrset->entry.data; uint8_t* newname, *dtarg = NULL; size_t newlen, dtarglen; - if(now > d->ttl) - return NULL; + time_t rr_ttl; + int graceperiod = 0; + if(TTL_IS_EXPIRED(d->ttl, now)) { + /* Allow TTL=0 DNAME from upstream within grace period */ + if(!(rrset->rk.flags & PACKED_RRSET_UPSTREAM_0TTL)) + return NULL; + rr_ttl = 0; + /* Since PACKED_RRSET_UPSTREAM_0TTL set the flag that + * the grace period has been applied, this stops the rrset + * from getting stored back into the cache with a bigger TTL.*/ + graceperiod = 1; + } else { + rr_ttl = d->ttl - now; + } /* only allow validated (with DNSSEC) DNAMEs used from cache * for insecure DNAMEs, query again. */ *sec_status = d->security; @@ -749,7 +811,7 @@ synth_dname_msg(struct ub_packed_rrset_k msg->rep->flags = BIT_QR; /* reply, no AA, no error */ msg->rep->authoritative = 0; /* reply stored in cache can't be authoritative */ msg->rep->qdcount = 1; - msg->rep->ttl = d->ttl - now; + msg->rep->ttl = rr_ttl; msg->rep->prefetch_ttl = PREFETCH_TTL_CALC(msg->rep->ttl); msg->rep->serve_expired_ttl = msg->rep->ttl + SERVE_EXPIRED_TTL; msg->rep->serve_expired_norec_ttl = 0; @@ -762,6 +824,8 @@ synth_dname_msg(struct ub_packed_rrset_k msg->rep->rrsets[0] = packed_rrset_copy_region(rrset, region, now); if(!msg->rep->rrsets[0]) /* copy DNAME */ return NULL; + if(graceperiod) + msg->rep->rrsets[0]->rk.flags |= PACKED_RRSET_0TTL_GRACE; /* synth CNAME rrset */ get_cname_target(rrset, &dtarg, &dtarglen); if(!dtarg) @@ -801,7 +865,7 @@ synth_dname_msg(struct ub_packed_rrset_k if(!newd) return NULL; ck->entry.data = newd; - newd->ttl = d->ttl - now; /* RFC6672: synth CNAME TTL == DNAME TTL */ + newd->ttl = rr_ttl; /* RFC6672: synth CNAME TTL == DNAME TTL */ newd->count = 1; newd->rrsig_count = 0; newd->trust = rrset_trust_ans_noAA; @@ -844,6 +908,8 @@ fill_any(struct module_env* env, /* set NOTIMPL for RFC 8482 */ msg->rep->flags |= LDNS_RCODE_NOTIMPL; msg->rep->security = sec_status_indeterminate; + msg->rep->ttl = 1; /* empty NOTIMPL response will never be + * updated with rrsets, set TTL to 1 */ return msg; } @@ -1013,7 +1079,7 @@ dns_cache_lookup(struct module_env* env, if(env->cfg->harden_below_nxdomain) { while(!dname_is_root(k.qname)) { if(dpname && dpnamelen - && !dname_subdomain_c(k.qname, dpname)) + && !dname_strict_subdomain_c(k.qname, dpname)) break; /* no synth nxdomain above the stub */ dname_remove_label(&k.qname, &k.qname_len); h = query_info_hash(&k, flags); @@ -1069,7 +1135,7 @@ dns_cache_store(struct module_env* env, msgqinf->qclass, flags, 0, 1); if(e) { struct reply_info* cached = e->entry.data; - if(cached->ttl < *env->now + if(TTL_IS_EXPIRED(cached->ttl, *env->now) && reply_info_could_use_expired(cached, *env->now) /* If we are validating make sure only * validating modules can update such messages. Index: sbin/unwind/libunbound/services/cache/dns.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/services/cache/dns.h,v diff -u -p -r1.7 dns.h --- sbin/unwind/libunbound/services/cache/dns.h 14 Sep 2025 15:16:53 -0000 1.7 +++ sbin/unwind/libunbound/services/cache/dns.h 21 Sep 2026 16:28:25 -0000 @@ -53,7 +53,7 @@ struct delegpt; * Must be an unsigned 32-bit value larger than 0xffff */ /** Allow caching a DNS message with a zero TTL. */ -#define DNSCACHE_STORE_ZEROTTL 0x100000 +#define DNSCACHE_STORE_EXPIRED_MSG_CACHEDB 0x100000 /** * Region allocated message reply Index: sbin/unwind/libunbound/services/cache/infra.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/services/cache/infra.c,v diff -u -p -r1.13 infra.c --- sbin/unwind/libunbound/services/cache/infra.c 29 Sep 2025 14:53:38 -0000 1.13 +++ sbin/unwind/libunbound/services/cache/infra.c 21 Sep 2026 16:28:25 -0000 @@ -1269,7 +1269,8 @@ int infra_wait_limit_allowed(struct infr int cookie_valid, struct config_file* cfg) { struct lruhash_entry* entry; - if(cfg->wait_limit == 0) + if(cfg->wait_limit == 0 || + (cookie_valid && cfg->wait_limit_cookie == 0)) return 1; entry = infra_find_ip_ratedata(infra, &rep->client_addr, Index: sbin/unwind/libunbound/services/cache/rrset.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/services/cache/rrset.c,v diff -u -p -r1.5 rrset.c --- sbin/unwind/libunbound/services/cache/rrset.c 29 Sep 2025 14:53:38 -0000 1.5 +++ sbin/unwind/libunbound/services/cache/rrset.c 21 Sep 2026 16:28:25 -0000 @@ -50,6 +50,7 @@ #include "util/regional.h" #include "util/alloc.h" #include "util/net_help.h" +#include "validator/val_utils.h" void rrset_markdel(void* key) @@ -126,12 +127,13 @@ rrset_cache_touch(struct rrset_cache* r, /** see if rrset needs to be updated in the cache */ static int -need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns) +need_to_update_rrset(void* nd, void* cd, time_t timenow, int equal, int ns, + int a_aaaa) { struct packed_rrset_data* newd = (struct packed_rrset_data*)nd; struct packed_rrset_data* cached = (struct packed_rrset_data*)cd; /* o if new data is expired, cached data is better */ - if( newd->ttl < timenow && timenow <= cached->ttl) + if( TTL_IS_EXPIRED(newd->ttl, timenow) && !TTL_IS_EXPIRED(cached->ttl, timenow)) return 0; /* o store if rrset has been validated * everything better than bogus data @@ -146,13 +148,27 @@ need_to_update_rrset(void* nd, void* cd, if( newd->trust > cached->trust ) { /* if the cached rrset is bogus, and new is equal, * do not update the TTL - let it expire. */ - if(equal && cached->ttl >= timenow && + if(equal && !TTL_IS_EXPIRED(cached->ttl, timenow) && cached->security == sec_status_bogus) return 0; + /* ghost-domain: never let an NS overwrite extend lifetime + * past the entry it replaces, regardless of trust. */ + /* Also for A/AAAA and it is glue. */ + if((ns || + (a_aaaa && cached->trust==rrset_trust_add_noAA)) + && !TTL_IS_EXPIRED(cached->ttl, timenow) && + newd->ttl > cached->ttl) { + size_t i; + if(a_aaaa) newd->trust=rrset_trust_add_noAA; + newd->ttl = cached->ttl; + for(i=0; i<(newd->count+newd->rrsig_count); i++) + if(newd->rr_ttl[i] > newd->ttl) + newd->rr_ttl[i] = newd->ttl; + } return 1; } /* o item in cache has expired */ - if( cached->ttl < timenow ) + if( TTL_IS_EXPIRED(cached->ttl, timenow) ) return 1; /* o same trust, but different in data - insert it */ if( newd->trust == cached->trust && !equal ) { @@ -199,6 +215,13 @@ rrset_cache_update(struct rrset_cache* r int equal = 0; log_assert(ref->id != 0 && k->id != 0); log_assert(k->rk.dname != NULL); + if((k->rk.flags&PACKED_RRSET_0TTL_GRACE) !=0) { + log_nametypeclass(VERB_ALGO, "rrset store of PACKED_RRSET_0TTL_GRACE rrset skipped", k->rk.dname, rrset_type, ntohs(k->rk.rrset_class)); + ub_packed_rrset_parsedelete(k, alloc); + return 0; /* Do not store 0TTL items after apply of + the grace ttl amount. + This means the ref was not changed by the call. */ + } /* looks up item with a readlock - no editing! */ if((e=slabhash_lookup(&r->table, h, k, 0)) != 0) { /* return id and key as they will be used in the cache @@ -213,7 +236,8 @@ rrset_cache_update(struct rrset_cache* r equal = rrsetdata_equal((struct packed_rrset_data*)k->entry. data, (struct packed_rrset_data*)e->data); if(!need_to_update_rrset(k->entry.data, e->data, timenow, - equal, (rrset_type==LDNS_RR_TYPE_NS))) { + equal, (rrset_type==LDNS_RR_TYPE_NS), + (rrset_type==LDNS_RR_TYPE_A || rrset_type==LDNS_RR_TYPE_AAAA))) { /* cache is superior, return that value */ lock_rw_unlock(&e->lock); ub_packed_rrset_parsedelete(k, alloc); @@ -245,12 +269,45 @@ rrset_cache_update(struct rrset_cache* r return 0; } +/** See if the name is a within signer authority */ +static int +dname_subdomain_rrsig_signers(uint8_t* dname, + struct ub_packed_rrset_key* rrset) +{ + struct packed_rrset_data* d = (struct packed_rrset_data*) + rrset->entry.data; + size_t i; + if(!d || !d->rrsig_count) + return 0; + for(i=0; irrsig_count; i++) { + uint8_t* sname = NULL; + size_t slen = 0; + rrsig_get_signer(d->rr_data[d->count+i], d->rr_len[d->count+i], + &sname, &slen); + if(!sname || !slen) + return 0; /* malformed */ + if(!dname_subdomain_c(dname, sname)) + return 0; /* not a subdomain */ + } + return 1; +} + void rrset_cache_update_wildcard(struct rrset_cache* rrset_cache, struct ub_packed_rrset_key* rrset, uint8_t* ce, size_t ce_len, struct alloc_cache* alloc, time_t timenow) { struct rrset_ref ref; uint8_t wc_dname[LDNS_MAX_DOMAINLEN+3]; + uint8_t* new_dname; + size_t new_dname_len; + + /* See if the RRSIG signer name allows this wildcard, + * the new rrset should fall within the zone of the RRSIG signer(s). */ + if(!dname_subdomain_rrsig_signers(ce, rrset)) { + verbose(VERB_ALGO, "wildcard canonical parent outside signer authority"); + return; + } + rrset = packed_rrset_copy_alloc(rrset, alloc, timenow); if(!rrset) { log_err("malloc failure in rrset_cache_update_wildcard"); @@ -262,14 +319,16 @@ void rrset_cache_update_wildcard(struct wc_dname[1] = (uint8_t)'*'; memmove(wc_dname+2, ce, ce_len); - free(rrset->rk.dname); - rrset->rk.dname_len = ce_len + 2; - rrset->rk.dname = (uint8_t*)memdup(wc_dname, rrset->rk.dname_len); - if(!rrset->rk.dname) { - alloc_special_release(alloc, rrset); + new_dname_len = ce_len + 2; + new_dname = (uint8_t*)memdup(wc_dname, new_dname_len); + if(!new_dname) { + ub_packed_rrset_parsedelete(rrset, alloc); log_err("memdup failure in rrset_cache_update_wildcard"); return; } + free(rrset->rk.dname); + rrset->rk.dname = new_dname; + rrset->rk.dname_len = new_dname_len; rrset->entry.hash = rrset_key_hash(&rrset->rk); ref.key = rrset; @@ -278,6 +337,10 @@ void rrset_cache_update_wildcard(struct (void)rrset_cache_update(rrset_cache, &ref, alloc, timenow); } +/** Grace period in seconds for TTL=0 DNAME rrsets (RFC 2308: do not cache). + * Allows synthesis from cache within this window to reduce recursion load. */ +#define DNAME_TTL0_GRACE_SECONDS 1 + struct ub_packed_rrset_key* rrset_cache_lookup(struct rrset_cache* r, uint8_t* qname, size_t qnamelen, uint16_t qtype, uint16_t qclass, uint32_t flags, time_t timenow, @@ -300,27 +363,36 @@ rrset_cache_lookup(struct rrset_cache* r /* check TTL */ struct packed_rrset_data* data = (struct packed_rrset_data*)e->data; - if(timenow > data->ttl) { - lock_rw_unlock(&e->lock); - return NULL; + struct ub_packed_rrset_key* k = (struct ub_packed_rrset_key*)e->key; + if(TTL_IS_EXPIRED(data->ttl, timenow)) { + /* Allow TTL=0 DNAME within grace period for synthesis */ + if(qtype == LDNS_RR_TYPE_DNAME && + (k->rk.flags & PACKED_RRSET_UPSTREAM_0TTL) && + (timenow - data->ttl_add) <= DNAME_TTL0_GRACE_SECONDS) { + /* within grace: allow for synthesis */ + } else { + lock_rw_unlock(&e->lock); + return NULL; + } } /* we're done */ - return (struct ub_packed_rrset_key*)e->key; + return k; } return NULL; } -int +int rrset_array_lock(struct rrset_ref* ref, size_t count, time_t timenow) { size_t i; + struct packed_rrset_data* d; for(i=0; i0 && ref[i].key == ref[i-1].key) continue; /* only lock items once */ lock_rw_rdlock(&ref[i].key->entry.lock); - if(ref[i].id != ref[i].key->id || timenow > - ((struct packed_rrset_data*)(ref[i].key->entry.data)) - ->ttl) { + d = ref[i].key->entry.data; + if(ref[i].id != ref[i].key->id || + TTL_IS_EXPIRED(d->ttl, timenow)) { /* failure! rollback our readlocks */ rrset_array_unlock(ref, i+1); return 0; @@ -511,7 +583,7 @@ rrset_cache_expired_above(struct rrset_c *qnamelen, searchtype, qclass, 0, 0, 0))) { struct packed_rrset_data* data = (struct packed_rrset_data*)rrset->entry.data; - if(now > data->ttl) { + if(TTL_IS_EXPIRED(data->ttl, now)) { /* it is expired, this is not wanted */ lock_rw_unlock(&rrset->entry.lock); log_nametypeclass(VERB_ALGO, "this rrset is expired", *qname, searchtype, qclass); Index: sbin/unwind/libunbound/sldns/keyraw.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/sldns/keyraw.c,v diff -u -p -r1.7 keyraw.c --- sbin/unwind/libunbound/sldns/keyraw.c 29 Sep 2025 14:53:38 -0000 1.7 +++ sbin/unwind/libunbound/sldns/keyraw.c 21 Sep 2026 16:28:25 -0000 @@ -67,19 +67,28 @@ sldns_rr_dnskey_key_size_raw(const unsig case LDNS_RSASHA512: #endif if (len > 0) { + size_t nlen, offset; if (keydata[0] == 0) { /* big exponent */ if (len > 3) { memmove(&int16, keydata + 1, 2); exp = ntohs(int16); - return (len - exp - 3)*8; + offset = 3; } else { return 0; } } else { exp = keydata[0]; - return (len-exp-1)*8; + offset = 1; } + if(exp+offset > len) + return 0; + nlen = len - exp - offset; + /* prefixed zeroes mean a smaller value */ + while(nlen > 0 && + keydata[len-nlen] == 0) + nlen--; + return nlen*8; } else { return 0; } Index: sbin/unwind/libunbound/sldns/rrdef.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/sldns/rrdef.h,v diff -u -p -r1.8 rrdef.h --- sbin/unwind/libunbound/sldns/rrdef.h 14 Sep 2025 15:16:53 -0000 1.8 +++ sbin/unwind/libunbound/sldns/rrdef.h 21 Sep 2026 16:28:25 -0000 @@ -480,11 +480,13 @@ enum sldns_enum_ede_code LDNS_EDE_TOO_EARLY = 26, LDNS_EDE_UNSUPPORTED_NSEC3_ITERATIONS = 27, LDNS_EDE_BADPROXYPOLICY = 28, - LDNS_EDE_SYNTHESIZED = 29 + LDNS_EDE_SYNTHESIZED = 29, + LDNS_EDE_INVALID_QUERY_TYPE = 30 }; typedef enum sldns_enum_ede_code sldns_ede_code; #define LDNS_EDNS_MASK_DO_BIT 0x8000 +#define LDNS_EDNS_MASK_CO_BIT 0x4000 /** TSIG and TKEY extended rcodes (16bit), 0-15 are the normal rcodes. */ #define LDNS_TSIG_ERROR_NOERROR 0 Index: sbin/unwind/libunbound/sldns/str2wire.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/sldns/str2wire.c,v diff -u -p -r1.12 str2wire.c --- sbin/unwind/libunbound/sldns/str2wire.c 29 Sep 2025 14:53:38 -0000 1.12 +++ sbin/unwind/libunbound/sldns/str2wire.c 21 Sep 2026 16:28:25 -0000 @@ -842,7 +842,8 @@ rrinternal_parse_rdata(sldns_buffer* str sldns_write_uint16(rr+dname_len+8, (uint16_t)(rr_cur_len-dname_len-10)); *rr_len = rr_cur_len; /* SVCB/HTTPS handling */ - if (rr_type == LDNS_RR_TYPE_SVCB || rr_type == LDNS_RR_TYPE_HTTPS) { + if ((rr_type == LDNS_RR_TYPE_SVCB || rr_type == LDNS_RR_TYPE_HTTPS) + && !was_unknown_rr_format) { size_t rdata_len = rr_cur_len - dname_len - 10; uint8_t *rdata = rr+dname_len + 10; @@ -1201,7 +1202,7 @@ sldns_str2wire_svcbparam_ipv4hint(const { size_t count; char ip_str[INET_ADDRSTRLEN+1]; - char *next_ip_str; + const char *next_ip_str; size_t i; for (i = 0, count = 1; val[i]; i++) { @@ -1256,7 +1257,7 @@ sldns_str2wire_svcbparam_ipv6hint(const { size_t count; char ip_str[INET6_ADDRSTRLEN+1]; - char *next_ip_str; + const char *next_ip_str; size_t i; for (i = 0, count = 1; val[i]; i++) { @@ -1317,7 +1318,7 @@ static int sldns_str2wire_svcbparam_mandatory(const char* val, uint8_t* rd, size_t* rd_len) { size_t i, count, val_len; - char* next_key; + const char* next_key; val_len = strlen(val); @@ -1410,6 +1411,7 @@ sldns_str2wire_svcbparam_ech_value(const return LDNS_WIREPARSE_ERR_BUFFER_TOO_SMALL; sldns_write_uint16(rd, SVCB_KEY_ECH); sldns_write_uint16(rd + 2, 0); + *rd_len = 4; return LDNS_WIREPARSE_ERR_OK; } Index: sbin/unwind/libunbound/sldns/wire2str.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/sldns/wire2str.c,v diff -u -p -r1.11 wire2str.c --- sbin/unwind/libunbound/sldns/wire2str.c 14 Sep 2025 15:16:53 -0000 1.11 +++ sbin/unwind/libunbound/sldns/wire2str.c 21 Sep 2026 16:28:25 -0000 @@ -233,6 +233,7 @@ static sldns_lookup_table sldns_edns_ede { LDNS_EDE_UNSUPPORTED_NSEC3_ITERATIONS, "Unsupported NSEC3 Iterations Value" }, { LDNS_EDE_BADPROXYPOLICY, "Unable to Conform to Policy" }, { LDNS_EDE_SYNTHESIZED, "Synthesized Answer" }, + { LDNS_EDE_INVALID_QUERY_TYPE, "Invalid Query Type" }, { 0, NULL} }; sldns_lookup_table* sldns_edns_ede_codes = sldns_edns_ede_codes_data; @@ -2485,6 +2486,8 @@ int sldns_wire2str_edns_scan(uint8_t** d w += sldns_str_print(str, str_len, " flags:"); if((edns_bits & LDNS_EDNS_MASK_DO_BIT)) w += sldns_str_print(str, str_len, " do"); + if((edns_bits & LDNS_EDNS_MASK_CO_BIT)) + w += sldns_str_print(str, str_len, " co"); /* the extended rcode is the value set, shifted four bits, * and or'd with the original rcode */ if(ext_rcode) { Index: sbin/unwind/libunbound/util/alloc.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/alloc.c,v diff -u -p -r1.7 alloc.c --- sbin/unwind/libunbound/util/alloc.c 23 Feb 2025 07:53:40 -0000 1.7 +++ sbin/unwind/libunbound/util/alloc.c 21 Sep 2026 16:28:25 -0000 @@ -328,7 +328,7 @@ size_t alloc_get_mem(struct alloc_cache* struct regional* alloc_reg_obtain(struct alloc_cache* alloc) { - if(alloc->num_reg_blocks > 0) { + if(alloc->num_reg_blocks > 0 && alloc->reg_list) { struct regional* r = alloc->reg_list; alloc->reg_list = (struct regional*)r->next; r->next = NULL; Index: sbin/unwind/libunbound/util/config_file.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/config_file.c,v diff -u -p -r1.20 config_file.c --- sbin/unwind/libunbound/util/config_file.c 29 Sep 2025 14:53:38 -0000 1.20 +++ sbin/unwind/libunbound/util/config_file.c 21 Sep 2026 16:28:25 -0000 @@ -46,6 +46,7 @@ #ifdef HAVE_TIME_H #include #endif +#include #include "util/log.h" #include "util/configyyrename.h" #include "util/config_file.h" @@ -62,6 +63,9 @@ #include "sldns/wire2str.h" #include "sldns/parseutil.h" #include "iterator/iterator.h" +#ifdef HAVE_SYS_STAT_H +#include +#endif #ifdef HAVE_GLOB_H # include #endif @@ -90,7 +94,7 @@ struct config_parser_state* cfg_parser = static void init_outgoing_availports(int* array, int num); /** init cookie with random data */ -static void init_cookie_secret(uint8_t* cookie_secret, size_t cookie_secret_len); +static int init_cookie_secret(struct config_file* cfg); struct config_file* config_create(void) @@ -129,6 +133,7 @@ config_create(void) cfg->tls_cert_bundle = NULL; cfg->tls_win_cert = 0; cfg->tls_use_sni = 1; + if(!(cfg->tls_protocols = strdup("TLSv1.2 TLSv1.3"))) goto error_exit; cfg->https_port = UNBOUND_DNS_OVER_HTTPS_PORT; if(!(cfg->http_endpoint = strdup("/dns-query"))) goto error_exit; cfg->http_max_streams = 100; @@ -147,6 +152,7 @@ config_create(void) cfg->log_local_actions = 0; cfg->log_servfail = 0; cfg->log_destaddr = 0; + cfg->log_thread_id = 0; #ifndef USE_WINSOCK # ifdef USE_MINI_EVENT /* select max 1024 sockets */ @@ -210,7 +216,7 @@ config_create(void) cfg->if_automatic = 0; cfg->if_automatic_ports = NULL; cfg->so_rcvbuf = 0; - cfg->so_sndbuf = 4*1024*1024; + cfg->so_sndbuf = 1*1024*1024; cfg->so_reuseport = REUSEPORT_DEFAULT; cfg->ip_transparent = 0; cfg->ip_freebind = 0; @@ -272,7 +278,7 @@ config_create(void) cfg->val_sig_skew_min = 3600; /* at least daylight savings trouble */ cfg->val_sig_skew_max = 86400; /* at most timezone settings trouble */ cfg->val_max_restart = 5; - cfg->val_clean_additional = 1; + cfg->val_clean_additional = 0; /* off to protect against much data. */ cfg->val_log_level = 0; cfg->val_log_squelch = 0; cfg->val_permissive_mode = 0; @@ -384,8 +390,7 @@ config_create(void) #endif cfg->do_answer_cookie = 0; memset(cfg->cookie_secret, 0, sizeof(cfg->cookie_secret)); - cfg->cookie_secret_len = 16; - init_cookie_secret(cfg->cookie_secret, cfg->cookie_secret_len); + cfg->cookie_secret_len = 0; /* not set yet */ cfg->cookie_secret_file = NULL; #ifdef USE_CACHEDB if(!(cfg->cachedb_backend = strdup("testframe"))) goto error_exit; @@ -421,7 +426,11 @@ config_create(void) cfg->dns_error_reporting = 0; cfg->iter_scrub_ns = 20; cfg->iter_scrub_cname = 11; + cfg->iter_scrub_rrsig = 8; + cfg->iter_scrub_promiscuous = 1; cfg->max_global_quota = 200; + cfg->val_validation_attempts = 32; + cfg->val_hash_attempts = 32; return cfg; error_exit: config_delete(cfg); @@ -526,7 +535,11 @@ probe_maxrto(int useful_server_top_timeo int config_apply_max_rtt(int max_rtt) { USEFUL_SERVER_TOP_TIMEOUT = max_rtt; - BLACKLIST_PENALTY = max_rtt*4; + BLACKLIST_PENALTY = +#ifdef INT_MAX + (max_rtt > INT_MAX/4) ? INT_MAX : +#endif + max_rtt*4; PROBE_MAXRTO = probe_maxrto(max_rtt); return max_rtt; } @@ -628,6 +641,11 @@ int config_set_option(struct config_file else S_STR("tls-ciphers:", tls_ciphers) else S_STR("tls-ciphersuites:", tls_ciphersuites) else S_YNO("tls-use-sni:", tls_use_sni) + else if(strcmp(opt, "tls-protocols:") == 0) { + if(!cfg_tls_protocols_is_valid(val)) return 0; + free(cfg->tls_protocols); + return (cfg->tls_protocols = strdup(val)) != NULL; + } else S_NUMBER_NONZERO("https-port:", https_port) else S_STR("http-endpoint:", http_endpoint) else S_NUMBER_NONZERO("http-max-streams:", http_max_streams) @@ -745,6 +763,7 @@ int config_set_option(struct config_file else S_YNO("log-local-actions:", log_local_actions) else S_YNO("log-servfail:", log_servfail) else S_YNO("log-destaddr:", log_destaddr) + else S_YNO("log-thread-id:", log_thread_id) else S_YNO("val-permissive-mode:", val_permissive_mode) else S_YNO("aggressive-nsec:", aggressive_nsec) else S_YNO("ignore-cd-flag:", ignore_cd) @@ -763,9 +782,13 @@ int config_set_option(struct config_file 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_NONZERO("iter-scrub-ns:", iter_scrub_ns) else S_NUMBER_OR_ZERO("iter-scrub-cname:", iter_scrub_cname) + else S_NUMBER_OR_ZERO("iter-scrub-rrsig:", iter_scrub_rrsig) + else S_YNO("iter-scrub-promiscuous:", iter_scrub_promiscuous) else S_NUMBER_OR_ZERO("max-global-quota:", max_global_quota) + else S_NUMBER_OR_ZERO("val-validation-attempts:", val_validation_attempts) + else S_NUMBER_OR_ZERO("val-hash-attempts:", val_hash_attempts) else S_YNO("serve-original-ttl:", serve_original_ttl) else S_STR("val-nsec3-keysize-iterations:", val_nsec3_key_iterations) else S_YNO("zonemd-permissive-mode:", zonemd_permissive_mode) @@ -1179,6 +1202,7 @@ config_get_option(struct config_file* cf else O_STR(opt, "tls-ciphers", tls_ciphers) else O_STR(opt, "tls-ciphersuites", tls_ciphersuites) else O_YNO(opt, "tls-use-sni", tls_use_sni) + else O_STR(opt, "tls-protocols", tls_protocols) else O_DEC(opt, "https-port", https_port) else O_STR(opt, "http-endpoint", http_endpoint) else O_UNS(opt, "http-max-streams", http_max_streams) @@ -1200,6 +1224,7 @@ config_get_option(struct config_file* cf else O_YNO(opt, "log-local-actions", log_local_actions) else O_YNO(opt, "log-servfail", log_servfail) else O_YNO(opt, "log-destaddr", log_destaddr) + else O_YNO(opt, "log-thread-id", log_thread_id) else O_STR(opt, "pidfile", pidfile) else O_YNO(opt, "hide-identity", hide_identity) else O_YNO(opt, "hide-version", hide_version) @@ -1241,7 +1266,11 @@ config_get_option(struct config_file* cf 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, "iter-scrub-rrsig", iter_scrub_rrsig) + else O_YNO(opt, "iter-scrub-promiscuous", iter_scrub_promiscuous) else O_DEC(opt, "max-global-quota", max_global_quota) + else O_DEC(opt, "val-validation-attempts", val_validation_attempts) + else O_DEC(opt, "val-hash-attempts", val_hash_attempts) else O_YNO(opt, "serve-original-ttl", serve_original_ttl) else O_STR(opt, "val-nsec3-keysize-iterations",val_nsec3_key_iterations) else O_YNO(opt, "zonemd-permissive-mode", zonemd_permissive_mode) @@ -1553,6 +1582,8 @@ config_read(struct config_file* cfg, con } globfree(&g); config_auto_slab_values(cfg); + if(!init_cookie_secret(cfg)) + return 0; return 1; } #endif /* HAVE_GLOB */ @@ -1577,6 +1608,8 @@ config_read(struct config_file* cfg, con } config_auto_slab_values(cfg); + if(!init_cookie_secret(cfg)) + return 0; return 1; } @@ -1747,6 +1780,7 @@ config_delete(struct config_file* cfg) config_delstrlist(cfg->tls_session_ticket_keys.first); free(cfg->tls_ciphers); free(cfg->tls_ciphersuites); + free(cfg->tls_protocols); free(cfg->http_endpoint); if(cfg->log_identity) { log_ident_revert_to_default(); @@ -1850,18 +1884,33 @@ config_delete(struct config_file* cfg) free(cfg); } -static void -init_cookie_secret(uint8_t* cookie_secret, size_t cookie_secret_len) +static int +init_cookie_secret(struct config_file* cfg) { - struct ub_randstate *rand = ub_initstate(NULL); + struct ub_randstate* rand; + size_t cookie_secret_len; + uint8_t* cookie_secret; + if(!cfg->do_answer_cookie) + return 1; + if(cfg->cookie_secret_file && cfg->cookie_secret_file[0]) + return 1; + if(cfg->cookie_secret_len != 0) + return 1; - if (!rand) - fatal_exit("could not init random generator"); + rand = ub_initstate(NULL); + if(!rand) { + log_err("init_cookie_secret: could not init random generator"); + return 0; + } + cfg->cookie_secret_len = 16; + cookie_secret_len = cfg->cookie_secret_len; + cookie_secret = cfg->cookie_secret; while (cookie_secret_len) { *cookie_secret++ = (uint8_t)ub_random(rand); cookie_secret_len--; } ub_randfree(rand); + return 1; } static void @@ -1924,7 +1973,7 @@ extract_port_from_str(const char* str, i int cfg_mark_ports(const char* str, int allow, int* avail, int num) { - char* mid = strchr(str, '-'); + const char* mid = strchr(str, '-'); #ifdef DISABLE_EXPLICIT_PORT_RANDOMISATION log_warn("Explicit port randomisation disabled, ignoring " "outgoing-port-permit and outgoing-port-avoid configuration " @@ -1932,7 +1981,7 @@ cfg_mark_ports(const char* str, int allo #endif if(!mid) { int port = extract_port_from_str(str, num); - if(port < 0) { + if (port < 0) { log_err("Failed to parse the port number"); return 0; } @@ -1942,7 +1991,7 @@ cfg_mark_ports(const char* str, int allo char buf[16]; int i, low; int high = extract_port_from_str(mid+1, num); - if(high < 0) { + if (high < 0) { log_err("Failed to parse the port number"); return 0; } @@ -1956,7 +2005,7 @@ cfg_mark_ports(const char* str, int allo memcpy(buf, str, (size_t)(mid-str)); buf[mid-str] = 0; low = extract_port_from_str(buf, num); - if(low < 0) { + if (low < 0) { log_err("Failed to parse the port number"); return 0; } @@ -2627,10 +2676,10 @@ fname_after_chroot(const char* fname, st } /** return next space character in string */ -static char* next_space_pos(const char* str) +static const char* next_space_pos(const char* str) { - char* sp = strchr(str, ' '); - char* tab = strchr(str, '\t'); + const char* sp = strchr(str, ' '); + const char* tab = strchr(str, '\t'); if(!tab && !sp) return NULL; if(!sp) return tab; @@ -2639,10 +2688,10 @@ static char* next_space_pos(const char* } /** return last space character in string */ -static char* last_space_pos(const char* str) +static const char* last_space_pos(const char* str) { - char* sp = strrchr(str, ' '); - char* tab = strrchr(str, '\t'); + const char* sp = strrchr(str, ' '); + const char* tab = strrchr(str, '\t'); if(!tab && !sp) return NULL; if(!sp) return tab; @@ -2700,8 +2749,8 @@ cfg_parse_local_zone(struct config_file* char* cfg_ptr_reverse(char* str) { - char* ip, *ip_end; - char* name; + const char* ip, *ip_end; + const char* name; char* result; char buf[1024]; struct sockaddr_storage addr; @@ -2852,7 +2901,7 @@ if_listens_on(const char* ifname, int de struct config_strlist* additional_ports) { struct config_strlist* s; - char* p = strchr(ifname, '@'); + const char* p = strchr(ifname, '@'); int if_port; if(p) if_port = atoi(p+1); else if_port = default_port; @@ -2920,6 +2969,29 @@ if_is_quic(const char* ifname, int defau } int +cfg_ports_list_contains(char* ports, int p) +{ + char* now = ports, *after; + int extraport; + while(now && *now) { + while(isspace((unsigned char)*now)) + now++; + if(!now) + break; + after = now; + extraport = (int)strtol(now, &after, 10); + if(extraport < 0 || extraport > 65535) + continue; /* Out of range. */ + if(extraport == 0 && now == after) + return 0; /* Number could not be parsed. */ + now = after; + if(extraport == p) + return 1; + } + return 0; +} + +int cfg_has_https(struct config_file* cfg) { int i; @@ -2927,6 +2999,8 @@ cfg_has_https(struct config_file* cfg) if(if_is_https(cfg->ifs[i], cfg->port, cfg->https_port)) return 1; } + if(cfg_ports_list_contains(cfg->if_automatic_ports, cfg->https_port)) + return 1; return 0; } @@ -2939,9 +3013,83 @@ cfg_has_quic(struct config_file* cfg) if(if_is_quic(cfg->ifs[i], cfg->port, cfg->quic_port)) return 1; } + if(cfg_ports_list_contains(cfg->if_automatic_ports, cfg->quic_port)) + return 1; return 0; #else (void)cfg; return 0; #endif +} + +int +cfg_tls_protocols_is_valid(const char* tls_protocols) +{ + const char* s = tls_protocols; + while(*s && isspace((unsigned char)*s)) s++; + while(*s && !isspace((unsigned char)*s)) { + if(strncmp(s, "TLSv1.2", 7) == 0 || + strncmp(s, "TLSv1.3", 7) == 0) { + s += 7; + if(*s && !isspace((unsigned char)*s)) { + /* something is attached; fail */ + return 0; + } + while(*s && isspace((unsigned char)*s)) + s++; + continue; + } + return 0; + } + return 1; +} + +void +cfg_tls_protocols_allowed(const char* tls_protocols, int* allow12, int* allow13) +{ + const char* s = tls_protocols; + *allow12 = 0; + *allow13 = 0; + if(tls_protocols == NULL) return; + while(*s && isspace((unsigned char)*s)) s++; + while(*s && !isspace((unsigned char)*s)) { + if(strncmp(s, "TLSv1.2", 7) == 0) { + *allow12 = 1; + s += 7; + } else if(strncmp(s, "TLSv1.3", 7) == 0) { + *allow13 = 1; + s += 7; + } else { + /* Unknown word, this should never happen but skip to + * be safe */ + while(*s && !isspace((unsigned char)*s)) + s++; + } + while(*s && isspace((unsigned char)*s)) + s++; + } +} + +int +file_get_mtime(const char* file, time_t* mtime, long* ns, int* nonexist) +{ + struct stat s; + if(stat(file, &s) != 0) { + *mtime = 0; + *ns = 0; + if(nonexist) + *nonexist = (errno == ENOENT); + return 0; + } + if(nonexist) + *nonexist = 0; + *mtime = s.st_mtime; +#ifdef HAVE_STRUCT_STAT_ST_MTIMENSEC + *ns = s.st_mtimensec; +#elif defined(HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC) + *ns = s.st_mtim.tv_nsec; +#else + *ns = 0; +#endif + return 1; } Index: sbin/unwind/libunbound/util/config_file.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/config_file.h,v diff -u -p -r1.20 config_file.h --- sbin/unwind/libunbound/util/config_file.h 29 Sep 2025 14:53:38 -0000 1.20 +++ sbin/unwind/libunbound/util/config_file.h 21 Sep 2026 16:28:25 -0000 @@ -148,6 +148,8 @@ struct config_file { char* tls_ciphersuites; /** if SNI is to be used */ int tls_use_sni; + /** TLS protocols */ + char* tls_protocols; /** port on which to provide DNS over HTTPS service */ int https_port; @@ -365,6 +367,8 @@ struct config_file { char* log_identity; /** log dest addr for log_replies */ int log_destaddr; + /** log linux thread ID */ + int log_thread_id; /** do not report identity (id.server, hostname.bind) */ int hide_identity; @@ -790,8 +794,17 @@ struct config_file { size_t iter_scrub_ns; /** limit on CNAME, DNAME RRs in answer for the iterator scrubber. */ int iter_scrub_cname; + /** limit on RRSIGs for an RRset for the iterator scrubber. */ + int iter_scrub_rrsig; /** limit on upstream queries for an incoming query and subqueries. */ int max_global_quota; + /** limit on validator validation attempts. */ + int val_validation_attempts; + /** limit on validator hash attempts. */ + int val_hash_attempts; + /** Should the iterator scrub promiscuous NS rrsets, from positive + * answers. */ + int iter_scrub_promiscuous; }; /** from cfg username, after daemonize setup performed */ @@ -875,6 +888,10 @@ struct config_auth { int zonemd_check; /** Reject absence of ZONEMD records, zone must have one */ int zonemd_reject_absence; + /** The maximum auth zone transfer size, in bytes. */ + size_t max_transfer_size; + /** The maximum auth zone transfer time taken, in msec. */ + int max_transfer_time; }; /** @@ -1477,5 +1494,31 @@ int cfg_has_quic(struct config_file* cfg /** get memory for string */ size_t getmem_str(char* str); + +/** + * See if the if_automatic_ports list contains the value. + * @param ports: String with port numbers. + * @param p: number looked for. + * @return true if found, false if not found or parse failure. + */ +int cfg_ports_list_contains(char* ports, int p); + +/** + * Check if the configured string contains supported TLS protocols. + * @param tls_protocols: String with TLS protocols. + * @return true if all options are valid, else false. + */ +int cfg_tls_protocols_is_valid(const char* tls_protocols); + +/** + * Based on the configured TLS protocols fill which ones are allowed. + * @param tls_protocols: String with TLS protocols. + * @param allow12: will be true if TLSv1.2 is configured. + * @param allow13: will be true if TLSv1.3 is configured. + */ +void cfg_tls_protocols_allowed(const char* tls_protocols, int* allow12, int* allow13); + +/** get the file mtime stat (or error, with errno and nonexist) */ +int file_get_mtime(const char* file, time_t* mtime, long* ns, int* nonexist); #endif /* UTIL_CONFIG_FILE_H */ Index: sbin/unwind/libunbound/util/configlexer.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/configlexer.c,v diff -u -p -r1.23 configlexer.c --- sbin/unwind/libunbound/util/configlexer.c 29 Sep 2025 14:53:38 -0000 1.23 +++ sbin/unwind/libunbound/util/configlexer.c 21 Sep 2026 16:28:27 -0000 @@ -5,7 +5,7 @@ #define YY_INT_ALIGNED short int -/* $OpenBSD: configlexer.c,v 1.23 2025/09/29 14:53:38 florian Exp $ */ +/* $OpenBSD: configlexer.c,v 1.27 2026/09/21 06:29:04 florian Exp $ */ /* A lexical scanner generated by flex */ @@ -27,7 +27,7 @@ /* end standard C headers. */ -/* $OpenBSD: configlexer.c,v 1.23 2025/09/29 14:53:38 florian Exp $ */ +/* $OpenBSD: configlexer.c,v 1.27 2026/09/21 06:29:04 florian Exp $ */ /* flex integer type definitions */ @@ -368,8 +368,8 @@ static void yy_fatal_error (yyconst char *yy_cp = '\0'; \ (yy_c_buf_p) = yy_cp; -#define YY_NUM_RULES 412 -#define YY_END_OF_BUFFER 413 +#define YY_NUM_RULES 420 +#define YY_END_OF_BUFFER 421 /* This struct is not used in this scanner, but its presence is necessary. */ struct yy_trans_info @@ -377,461 +377,471 @@ struct yy_trans_info flex_int32_t yy_verify; flex_int32_t yy_nxt; }; -static yyconst flex_int16_t yy_accept[4118] = +static yyconst flex_int16_t yy_accept[4207] = { 0, - 1, 1, 386, 386, 390, 390, 394, 394, 398, 398, - 1, 1, 402, 402, 406, 406, 413, 410, 1, 384, - 384, 411, 2, 411, 410, 410, 410, 410, 410, 410, - 410, 410, 410, 410, 410, 410, 410, 410, 410, 410, - 410, 410, 410, 410, 410, 410, 410, 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, 411, 409, 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, + 1, 1, 394, 394, 398, 398, 402, 402, 406, 406, + 1, 1, 410, 410, 414, 414, 421, 418, 1, 392, + 392, 419, 2, 419, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 394, 395, 395, + 396, 419, 398, 399, 399, 400, 419, 405, 402, 403, + 403, 404, 419, 406, 407, 407, 408, 419, 417, 393, + 2, 397, 419, 417, 413, 410, 411, 411, 412, 419, + 414, 415, 415, 416, 419, 418, 0, 1, 2, 2, + 2, 2, 418, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 394, 0, 398, 0, 405, 0, + 402, 406, 0, 417, 0, 2, 2, 417, 413, 0, + 410, 414, 0, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 417, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 380, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 141, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 151, 418, 418, 418, 418, + 418, 418, 418, 418, 417, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 123, 418, 418, 379, + 418, 418, 418, 418, 418, 418, 418, 418, 8, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 142, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 156, 418, + 418, 418, 417, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 369, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 417, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 74, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 279, + 418, 14, 15, 418, 418, 20, 19, 418, 418, 253, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 149, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 251, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 3, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 417, 418, 418, 418, 418, 418, 418, 418, 418, + 348, 418, 418, 418, 347, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + + 401, 418, 418, 418, 418, 418, 418, 418, 418, 73, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 77, + 418, 317, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 370, 371, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 78, 418, 418, 150, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 145, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 240, 418, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 22, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 177, 418, 418, 418, 418, 418, 418, 417, 401, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 121, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 325, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, 16, 418, + 418, 418, 418, 418, 418, 418, 418, 205, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 176, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 120, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 37, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 38, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 75, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 148, 418, + + 418, 418, 417, 418, 418, 418, 418, 418, 418, 140, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 76, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 283, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 206, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 63, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 59, 60, 418, + 303, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 68, 418, 69, 418, 418, + + 418, 418, 418, 418, 124, 418, 125, 418, 418, 418, + 418, 418, 122, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 7, + 418, 418, 418, 418, 418, 417, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 268, + 418, 418, 418, 418, 418, 418, 180, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 284, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 52, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 64, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 231, 418, 230, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 17, 18, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 79, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 239, 418, 418, 418, 418, 418, 418, 418, 127, + 418, 126, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 219, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + + 418, 157, 418, 259, 418, 418, 418, 417, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 115, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 101, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 252, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 106, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 72, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 223, 224, 418, + 418, 418, 418, 418, 319, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 6, 418, 418, 418, 418, 418, 418, + 418, 338, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 323, 418, 418, 418, 418, + + 418, 418, 418, 349, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 48, + 418, 418, 418, 418, 418, 418, 50, 418, 418, 418, + 102, 418, 418, 418, 418, 418, 61, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 417, 418, 215, 418, 418, 418, 152, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 244, 418, 418, 216, 418, 418, 418, + 418, 418, 418, 264, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 62, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 154, 133, 418, + 134, 418, 418, 418, 418, 132, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 173, 418, 418, + 57, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 301, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 217, 418, 418, 418, 418, + 418, 228, 220, 418, 227, 418, 418, 418, 222, 418, + + 418, 418, 418, 418, 418, 418, 418, 263, 418, 418, + 418, 418, 418, 418, 267, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 119, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 146, 418, 418, 418, 418, 418, 418, 418, 418, + 70, 418, 418, 418, 418, 31, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 21, 418, + 418, 418, 418, 418, 418, 418, 418, 32, 41, 418, + 185, 418, 418, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, 418, 213, + 418, 418, 417, 418, 418, 418, 418, 374, 418, 418, + 87, 418, 90, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 375, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 327, 418, 418, 418, 418, 280, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 135, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 172, 418, 53, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 274, 418, 418, 418, 418, 418, 418, 418, 418, 342, + 418, 418, 418, 418, 418, 383, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 229, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 179, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 336, 418, 418, 418, 418, 250, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 360, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 198, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, 128, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 51, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 192, 418, 418, 207, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 417, 418, 160, + 418, 418, 418, 418, 418, 418, 418, 418, 114, 418, + 418, 418, 418, 242, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 265, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 292, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 153, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 196, 418, 418, 418, 418, 418, + 418, 418, 91, 418, 92, 418, 418, 418, 418, 418, + 277, 418, 418, 418, 418, 418, 71, 345, 418, 418, + 418, 418, 418, 418, 418, 418, 100, 208, 418, 232, + 418, 269, 418, 418, 221, 320, 418, 418, 418, 418, + 418, 315, 418, 418, 418, 418, 418, 83, 418, 210, + 418, 418, 418, 418, 418, 418, 9, 418, 418, 418, + 418, 418, 118, 418, 418, 418, 418, 418, 418, 307, + + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 241, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 417, 418, 418, 418, 418, 195, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 197, 258, 181, 418, 418, 326, 418, + + 418, 418, 418, 418, 291, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 254, 418, 418, + 418, 418, 418, 418, 318, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 178, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 346, 418, 418, 418, + 418, 209, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 82, 84, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 117, 418, 418, 418, + + 418, 418, 418, 305, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 322, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 246, 418, 39, 33, 35, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 40, + 418, 34, 36, 418, 42, 418, 418, 418, 418, 418, + 418, 418, 113, 418, 418, 191, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 417, 418, 418, 418, + 418, 418, 418, 418, 418, 350, 418, 418, 418, 418, + 418, 248, 245, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 81, 418, 418, 418, 155, + 418, 136, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 174, 54, 418, 418, 418, 409, + 13, 418, 418, 418, 418, 418, 418, 418, 161, 418, + 418, 418, 418, 418, 418, 418, 418, 340, 418, 343, + 418, 384, 418, 385, 418, 418, 418, 418, 418, 386, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 12, + 418, 418, 23, 418, 418, 418, 418, 418, 418, 418, + 311, 418, 418, 418, 418, 367, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 324, 418, 418, 418, 418, + 85, 418, 256, 418, 418, 418, 418, 418, 247, 418, + 418, 418, 418, 80, 418, 418, 418, 418, 418, 418, + 24, 418, 418, 49, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 190, 189, 418, + 418, 418, 418, 418, 409, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 249, 243, 418, 418, + 418, 266, 418, 418, 328, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 203, 418, 418, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 93, 418, 418, 418, 418, 418, + 418, 418, 418, 306, 418, 418, 418, 418, 418, 226, + 418, 418, 418, 418, 418, 389, 390, 418, 255, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 313, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 352, 418, 356, 354, 187, 418, 418, 418, 86, 418, + 418, 418, 418, 199, 418, 418, 418, 418, 418, 129, + 131, 130, 418, 418, 418, 26, 418, 418, 182, 418, + 184, 418, 233, 418, 418, 418, 388, 418, 188, 418, + + 418, 418, 260, 418, 418, 418, 418, 270, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 163, 376, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 299, 418, 418, 282, 418, 418, 418, 418, 418, 418, + 418, 377, 418, 28, 418, 321, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 98, 234, 418, 418, 276, + 418, 418, 418, 304, 418, 344, 418, 418, 225, 418, + 418, 316, 418, 418, 418, 314, 65, 418, 418, 418, + 418, 418, 418, 418, 4, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 144, 418, 162, + 418, 418, 418, 204, 30, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 273, 43, 44, + 418, 418, 418, 418, 418, 418, 418, 381, 418, 418, + 329, 418, 418, 418, 418, 418, 418, 418, 290, 418, + 418, 418, 418, 418, 418, 418, 418, 237, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 97, 96, 418, 418, 66, 418, + 418, 302, 310, 418, 418, 278, 418, 418, 418, 418, + + 418, 11, 418, 418, 418, 418, 382, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 143, + 418, 418, 418, 418, 418, 418, 235, 103, 418, 418, + 46, 418, 418, 418, 418, 418, 418, 418, 418, 194, + 418, 418, 261, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 165, 418, 418, 418, 418, 281, 418, 418, + 418, 418, 418, 289, 418, 418, 418, 418, 158, 418, + 418, 418, 137, 139, 138, 418, 418, 418, 105, 110, + 104, 418, 418, 175, 418, 418, 418, 418, 94, 418, + 275, 312, 418, 418, 418, 418, 418, 418, 418, 10, + + 418, 418, 418, 418, 418, 308, 418, 418, 366, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 373, 45, 418, 418, 418, 418, 418, 193, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 111, + 109, 418, 418, 418, 58, 418, 418, 95, 418, 341, + 418, 418, 418, 418, 418, 25, 418, 418, 418, 418, + 418, 218, 418, 418, 362, 364, 418, 418, 418, 418, + 418, 361, 358, 418, 418, 418, 418, 236, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 418, 418, 214, + 418, 418, 183, 88, 89, 418, 418, 418, 418, 418, + 418, 330, 418, 418, 418, 418, 418, 418, 418, 286, + 418, 418, 285, 159, 418, 418, 108, 418, 107, 55, + 418, 418, 391, 166, 167, 170, 171, 168, 169, 99, + 339, 418, 418, 309, 418, 418, 418, 418, 418, 418, + 147, 418, 418, 418, 418, 27, 418, 186, 418, 418, + 418, 418, 418, 418, 212, 418, 272, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + + 418, 418, 418, 418, 418, 418, 418, 201, 200, 238, + 47, 418, 418, 418, 418, 387, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 337, 418, + 418, 418, 368, 418, 418, 418, 418, 418, 418, 418, + 116, 418, 418, 271, 418, 418, 300, 334, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 378, + 418, 112, 56, 67, 5, 418, 418, 353, 418, 357, + 355, 418, 418, 257, 418, 418, 418, 418, 335, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 287, 29, + + 418, 418, 418, 418, 418, 418, 262, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 288, 418, 418, + 418, 418, 418, 418, 418, 164, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 202, 418, 211, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 363, + 365, 359, 418, 418, 331, 418, 418, 418, 418, 418, + 418, 418, 418, 418, 418, 418, 418, 418, 418, 418, + 418, 418, 418, 372, 351, 418, 418, 295, 418, 418, + 418, 418, 418, 332, 418, 418, 418, 418, 418, 418, + 333, 418, 418, 418, 293, 418, 296, 297, 418, 418, - 410, 331, 410, 410, 410, 291, 410, 294, 295, 410, - 410, 410, 410, 410, 292, 296, 0 + 418, 418, 418, 294, 298, 0 } ; static yyconst flex_int32_t yy_ec[256] = @@ -874,17 +884,17 @@ static yyconst flex_int32_t yy_meta[41] 1, 1, 1, 1, 1, 1, 1, 1, 1, 1 } ; -static yyconst flex_int16_t yy_base[4136] = +static yyconst flex_int16_t yy_base[4225] = { 0, 0, 0, 38, 41, 44, 46, 59, 65, 71, 77, - 90, 112, 96, 118, 124, 136, 3759, 3487, 81, 8023, - 8023, 8023, 129, 52, 137, 63, 130, 159, 70, 132, + 90, 112, 96, 118, 124, 136, 4011, 3391, 81, 8183, + 8183, 8183, 129, 52, 137, 63, 130, 159, 70, 132, 134, 146, 57, 88, 76, 176, 178, 95, 200, 161, - 188, 202, 169, 194, 219, 97, 148, 3112, 8023, 8023, - 8023, 165, 3078, 8023, 8023, 8023, 221, 2637, 2599, 8023, - 8023, 8023, 239, 2469, 8023, 8023, 8023, 243, 1903, 8023, - 247, 8023, 251, 231, 1775, 1735, 8023, 8023, 8023, 258, - 1620, 8023, 8023, 8023, 262, 1495, 266, 198, 0, 270, + 188, 202, 169, 194, 219, 97, 148, 3359, 8183, 8183, + 8183, 165, 2999, 8183, 8183, 8183, 221, 2797, 2546, 8183, + 8183, 8183, 239, 2348, 8183, 8183, 8183, 243, 1989, 8183, + 247, 8183, 251, 231, 1900, 1884, 8183, 8183, 8183, 258, + 1737, 8183, 8183, 8183, 262, 1636, 266, 198, 0, 270, 0, 0, 223, 192, 236, 250, 255, 264, 268, 272, 92, 267, 266, 273, 277, 278, 282, 289, 290, 292, @@ -893,8 +903,8 @@ static yyconst flex_int16_t yy_base[4136 345, 152, 346, 348, 349, 353, 356, 360, 358, 363, 359, 361, 372, 371, 370, 373, 379, 167, 395, 387, 383, 400, 390, 394, 388, 403, 410, 402, 411, 405, - 408, 415, 422, 423, 1271, 434, 1215, 325, 1097, 439, - 1058, 970, 444, 941, 448, 452, 0, 377, 819, 456, + 408, 415, 422, 423, 1425, 434, 1275, 325, 1010, 439, + 982, 941, 444, 849, 448, 452, 0, 377, 819, 456, 570, 428, 460, 448, 460, 455, 456, 457, 459, 461, 458, 462, 463, 465, 464, 468, 476, 488, 475, 486, @@ -911,888 +921,908 @@ static yyconst flex_int16_t yy_base[4136 684, 715, 716, 717, 725, 718, 720, 685, 727, 730, 734, 723, 736, 738, 733, 743, 745, 746, 747, 751, - 740, 8023, 761, 752, 763, 762, 771, 768, 753, 769, + 740, 8183, 761, 752, 763, 762, 771, 768, 753, 769, 773, 776, 777, 775, 778, 779, 780, 782, 783, 784, 786, 790, 802, 791, 804, 800, 798, 812, 811, 813, 826, 787, 815, 816, 847, 817, 818, 822, 837, 829, 851, 853, 842, 855, 858, 859, 860, 827, 861, 863, 871, 879, 881, 832, 869, 883, 891, 886, 887, 889, - 890, 899, 900, 8023, 894, 892, 902, 908, 910, 917, + 890, 899, 900, 8183, 894, 892, 902, 908, 910, 917, 904, 929, 924, 907, 925, 934, 931, 932, 946, 968, - 933, 935, 936, 939, 944, 8023, 957, 948, 992, 950, + 933, 935, 936, 939, 944, 8183, 957, 948, 992, 950, 952, 978, 979, 975, 942, 966, 982, 974, 980, 996, - 849, 986, 993, 1000, 1015, 998, 1002, 1010, 1001, 1018, - 1020, 1017, 1033, 1028, 1024, 1026, 1031, 1034, 1035, 1042, - 1037, 895, 1040, 1054, 1039, 1041, 1047, 1050, 1043, 1056, - 1055, 1065, 1069, 1070, 1071, 1064, 1075, 1076, 1077, 1079, - 1078, 1101, 1088, 1094, 1091, 1080, 1099, 1110, 1081, 1105, - 1109, 1117, 1107, 1116, 1123, 1121, 1126, 1127, 1128, 1129, - 1130, 1138, 1135, 1137, 1139, 1143, 1144, 1145, 1147, 1151, - 1152, 1153, 1155, 1157, 1158, 1159, 1161, 1168, 1165, 1162, - - 1175, 1177, 1178, 1183, 1179, 8023, 1187, 1185, 8023, 1188, - 1189, 1190, 1191, 1192, 1193, 1194, 1195, 8023, 1202, 1203, - 1196, 1210, 1205, 1212, 1208, 1217, 1229, 1225, 1218, 1228, - 1231, 1233, 1235, 1237, 1244, 1240, 1242, 1249, 1241, 1248, - 1251, 1254, 1252, 1257, 1258, 1261, 1259, 1262, 1265, 1266, - 1285, 8023, 1268, 1269, 1272, 1277, 1270, 1292, 1280, 1294, - 1303, 1295, 1302, 1300, 1306, 1320, 1309, 1313, 1318, 1317, - 1322, 1282, 1323, 1330, 1326, 1332, 1328, 1333, 1335, 1336, - 1345, 1337, 1338, 1347, 1349, 8023, 1339, 1352, 1356, 1359, - 1370, 1353, 1366, 1367, 1368, 1375, 1372, 1371, 1373, 1378, - - 1374, 1379, 1380, 1384, 1396, 1385, 1398, 1399, 1394, 1401, - 1395, 1400, 1402, 1408, 1410, 1405, 1411, 1416, 1425, 1418, - 1422, 1429, 1435, 1440, 1437, 1439, 1447, 1449, 1426, 1442, - 1445, 1414, 1446, 1450, 1452, 1453, 1454, 1455, 1458, 1461, - 1468, 1464, 1466, 1467, 1471, 1472, 1473, 1475, 1479, 1482, - 1480, 1481, 1483, 1494, 1491, 1492, 1501, 1489, 1510, 1498, - 1502, 1514, 1515, 1508, 1517, 8023, 1521, 1529, 1525, 1527, - 1531, 1526, 1528, 1536, 1537, 1538, 1540, 1541, 1543, 1544, - 1546, 1551, 1552, 1553, 1547, 1555, 1559, 1563, 1565, 1564, - 1493, 1574, 1569, 1567, 1585, 1571, 1576, 1584, 1578, 1586, - - 1588, 1590, 1591, 1598, 1594, 1603, 1601, 1593, 1606, 1605, - 1613, 1609, 1608, 1615, 1614, 1628, 1625, 1616, 1617, 1629, - 1630, 1636, 1632, 1638, 1641, 1649, 1642, 1651, 1658, 1660, - 1653, 1662, 1655, 1663, 1667, 1668, 1669, 1671, 1672, 1670, - 1679, 1676, 1675, 1677, 1681, 1682, 1683, 1694, 1693, 1701, - 1685, 1698, 1699, 1703, 1704, 1707, 1709, 1710, 1714, 1715, - 1716, 1717, 1718, 1719, 1727, 1720, 1738, 1729, 1731, 1740, - 1732, 1739, 1745, 1747, 1749, 1748, 1752, 1753, 1754, 1758, - 1759, 1756, 1765, 1767, 1768, 1770, 1771, 1769, 1783, 1784, - 1785, 1786, 1773, 1791, 1792, 1793, 1794, 1795, 1798, 1801, - - 1805, 1806, 1803, 8023, 1809, 1819, 1814, 1815, 1817, 1818, - 1820, 1822, 1829, 1831, 1824, 1826, 1827, 1836, 1837, 1838, - 1863, 8023, 1842, 8023, 8023, 1846, 1839, 8023, 8023, 1844, - 1849, 8023, 1847, 1860, 1850, 1848, 1867, 1851, 1873, 1870, - 1861, 1876, 1877, 1884, 1898, 1886, 1887, 1880, 1889, 1891, - 1888, 1904, 1909, 1894, 1915, 1896, 1893, 1922, 1927, 1923, - 1928, 1931, 1932, 1933, 1935, 1936, 1938, 1942, 1945, 1944, - 1948, 1949, 1950, 1951, 1954, 1952, 1957, 1955, 1959, 1961, - 1962, 1964, 1965, 1966, 1978, 1969, 1981, 1990, 8023, 1986, - 1993, 1983, 1976, 1992, 1995, 2002, 1998, 2005, 1997, 2001, - - 2004, 2009, 2014, 2006, 2010, 2016, 2017, 2019, 2020, 2021, - 2025, 2026, 2029, 2031, 2030, 2033, 2042, 2035, 2037, 8023, - 2043, 2044, 2046, 2048, 2049, 2047, 2050, 2054, 2055, 2058, - 2063, 2068, 2061, 2051, 2069, 2070, 2080, 2077, 2081, 2084, - 2085, 2086, 2087, 2088, 2089, 8023, 2094, 2098, 2093, 2102, - 2101, 2103, 2090, 2105, 2109, 2112, 2115, 2113, 2116, 2117, - 2118, 2127, 2119, 2126, 2123, 2129, 2130, 2134, 2133, 2142, - 2145, 2147, 2143, 2149, 2151, 2152, 2153, 2154, 2155, 2157, - 2158, 2159, 2170, 2171, 2166, 2173, 2168, 2163, 2181, 2190, - 2185, 2186, 2187, 2188, 2191, 2194, 2198, 2202, 2197, 2201, - - 2203, 2210, 2206, 2209, 2211, 2214, 2213, 2217, 2231, 2221, - 2224, 2222, 2215, 2232, 2234, 2238, 2239, 8023, 2240, 2241, - 2242, 8023, 2244, 2246, 2247, 2269, 2248, 2250, 2259, 2260, - 2262, 2254, 2277, 2267, 2271, 2265, 2270, 2288, 2289, 2297, - 2292, 2294, 2295, 2298, 2304, 2300, 2302, 2306, 2315, 2310, - 2316, 2317, 2318, 2321, 2324, 2328, 2338, 2334, 2340, 2342, - 2325, 2337, 2339, 2358, 2341, 2343, 2346, 2349, 2344, 2350, - 2354, 2351, 2352, 2367, 2363, 2369, 2370, 2379, 2371, 2375, - 2374, 2380, 2383, 2385, 2390, 2391, 2393, 8023, 2400, 2273, - 2397, 2399, 2398, 2408, 2405, 2406, 8023, 2409, 2412, 2407, - - 2420, 2415, 2417, 2419, 2422, 2424, 2428, 2429, 2431, 2433, - 2432, 2434, 2440, 2435, 2453, 8023, 2439, 8023, 2448, 2437, - 2449, 2454, 2456, 2464, 2459, 2460, 2463, 2465, 2466, 2467, - 8023, 8023, 2468, 2470, 2476, 2482, 2490, 2492, 2487, 2488, - 2489, 8023, 2477, 2500, 8023, 2497, 2491, 2504, 2495, 2505, - 2508, 2510, 2514, 2515, 2511, 2516, 2517, 2520, 2519, 2529, - 2521, 2542, 2522, 2538, 2512, 8023, 2539, 2544, 2524, 2546, - 2548, 2549, 2550, 2552, 2555, 2554, 8023, 2556, 2558, 2561, - 2563, 2570, 2569, 2571, 2572, 2573, 2577, 2575, 2579, 2581, - 2582, 2583, 2592, 2594, 2595, 2597, 2599, 2606, 2603, 2611, - - 8023, 2607, 2591, 2610, 2619, 2615, 2617, 2614, 2618, 2621, - 2622, 2624, 2625, 2629, 2631, 2633, 2634, 2635, 2636, 2645, - 2650, 2641, 2646, 2649, 2653, 2654, 2657, 2658, 2663, 2660, - 2661, 2662, 2664, 8023, 2665, 2666, 2674, 2671, 2677, 2680, - 2667, 216, 2683, 2686, 2688, 2690, 2693, 2691, 2699, 2692, - 2709, 2710, 2705, 2696, 2707, 2714, 2715, 2716, 2694, 2718, - 2720, 2722, 2724, 2726, 2727, 2730, 2728, 8023, 2736, 2738, - 2740, 2733, 2731, 2754, 2741, 2751, 2739, 2750, 8023, 2758, - 2760, 2763, 2771, 2746, 2765, 2767, 2772, 2773, 2776, 2774, - 8023, 2777, 2779, 2784, 2786, 2785, 2787, 2788, 2789, 8023, - - 2803, 2795, 2804, 2791, 2805, 2793, 2806, 2807, 2812, 2813, - 2814, 2816, 2818, 2821, 2819, 2820, 2824, 2823, 2828, 2834, - 2836, 2835, 2837, 2839, 2844, 2846, 2840, 2847, 2849, 2853, - 2860, 2850, 8023, 2864, 2861, 2863, 2867, 2851, 2862, 2879, - 2869, 2886, 2872, 2873, 2882, 2888, 2896, 2890, 2893, 2894, - 2908, 2898, 2907, 2910, 2911, 2922, 2913, 2921, 2923, 2917, - 2927, 2929, 2925, 2930, 2931, 2939, 2941, 2937, 2942, 2944, - 2947, 2946, 2949, 2956, 2953, 2961, 2957, 2954, 2963, 2965, - 2966, 2968, 2969, 2975, 2977, 8023, 2980, 2978, 2986, 2987, - 2989, 2991, 2995, 3002, 2997, 2999, 3000, 3003, 2992, 3007, - - 3011, 3008, 3014, 3015, 3017, 3018, 3025, 3020, 3026, 3027, - 3028, 3039, 3031, 3024, 3030, 3040, 3041, 3043, 3047, 3049, - 3051, 3052, 3053, 8023, 3056, 3060, 3054, 3061, 3063, 3067, - 3069, 3071, 3074, 3075, 3076, 3077, 3081, 3082, 2883, 3083, - 3084, 3091, 3088, 3090, 3092, 3089, 8023, 3100, 3095, 3101, - 3106, 3105, 3108, 3109, 3115, 3118, 3122, 3123, 3125, 3116, - 3126, 3128, 3129, 8023, 3137, 3139, 3136, 3138, 3146, 3144, - 3145, 3147, 3149, 3150, 3151, 8023, 3152, 3154, 3155, 3159, - 3156, 3160, 3167, 3168, 3163, 3166, 8023, 3179, 3175, 3178, - 3180, 3187, 3182, 3184, 3186, 3188, 3190, 3193, 3194, 3197, - - 3199, 3203, 3208, 3201, 3205, 8023, 3209, 3211, 3214, 3218, - 3216, 3220, 3222, 3229, 3226, 3230, 3232, 3236, 3233, 3246, - 3235, 8023, 3257, 3223, 3252, 3243, 3259, 3255, 3260, 3261, - 3262, 3263, 3264, 3265, 3270, 3266, 3272, 8023, 3273, 3275, - 3276, 3277, 3280, 3281, 3282, 3291, 3288, 3289, 3295, 3296, - 3297, 3298, 3302, 3303, 3304, 3315, 3306, 3309, 3317, 3307, - 3316, 3318, 3326, 3327, 3329, 3330, 3338, 3339, 3334, 3342, - 3345, 3340, 3335, 3337, 3347, 3356, 3359, 3360, 3361, 3363, - 8023, 3366, 3367, 3368, 3355, 3357, 3370, 3372, 3374, 3375, - 3378, 3380, 3392, 3389, 3379, 3382, 3396, 3403, 3400, 3391, - - 3405, 3399, 3407, 3408, 3409, 3410, 3412, 3413, 3416, 3421, - 3419, 3428, 3420, 3423, 3425, 3427, 3436, 3432, 3435, 3445, - 3437, 3446, 3442, 3444, 3447, 3448, 3450, 3449, 3454, 3457, - 3459, 3452, 3460, 3465, 3473, 3475, 3476, 3478, 3480, 3468, - 3485, 3484, 8023, 8023, 3486, 8023, 3489, 3491, 3495, 3498, - 3499, 3502, 3500, 3503, 3504, 3510, 3506, 3518, 3514, 3517, - 3522, 3519, 3521, 3527, 3526, 3532, 3528, 3533, 3540, 3536, - 8023, 3538, 8023, 3545, 3541, 3542, 3543, 3554, 3549, 8023, - 3552, 8023, 3555, 3560, 3557, 3561, 3563, 8023, 3564, 3565, - 3568, 3566, 3570, 3571, 3574, 3576, 3580, 3578, 3581, 3591, - - 3592, 3587, 3582, 3594, 3598, 3584, 3601, 3603, 3606, 3605, - 3607, 3612, 3614, 3608, 3615, 3613, 3619, 3620, 3621, 3626, - 3627, 8023, 3630, 3640, 3633, 3637, 3641, 3642, 3643, 3648, - 3644, 3651, 3647, 3657, 3652, 3649, 3655, 3668, 3656, 3667, - 3659, 3680, 3660, 3677, 3671, 3681, 3684, 3692, 3674, 3693, - 3685, 8023, 3688, 3696, 3697, 3698, 3699, 3700, 8023, 3703, - 3705, 3701, 3711, 3713, 3707, 3709, 3715, 3719, 3723, 3718, - 3720, 3726, 3731, 3728, 3735, 3733, 3739, 8023, 3741, 3743, - 3744, 3751, 3753, 3747, 3761, 3762, 3759, 3765, 3767, 3763, - 3770, 3760, 3772, 3774, 3776, 3777, 3784, 3785, 3787, 3783, - - 3792, 3782, 3789, 3798, 3795, 3791, 3799, 3801, 3802, 3803, - 3804, 3807, 3811, 3812, 3810, 3806, 3813, 3827, 3814, 3808, - 8023, 3818, 3823, 3832, 3840, 3836, 3837, 3838, 3841, 3839, - 3843, 3848, 8023, 3847, 3849, 3854, 3850, 3851, 3861, 3863, - 3864, 3865, 3866, 3867, 3871, 3872, 3873, 3868, 8023, 3874, - 8023, 3878, 3880, 3887, 3892, 3898, 3895, 3893, 3899, 3900, - 3904, 3901, 3906, 3908, 3909, 3912, 3916, 3910, 3918, 3920, - 3921, 3924, 3922, 3934, 3927, 3929, 3936, 3945, 3928, 3932, - 3940, 3942, 3947, 3948, 3955, 3957, 3956, 8023, 8023, 3950, - 3958, 3965, 3967, 3963, 3969, 3972, 3980, 3974, 3971, 3984, - - 3988, 3989, 3991, 3982, 3992, 3996, 4003, 8023, 3998, 4001, - 3999, 4004, 4005, 4017, 4006, 4008, 4026, 4010, 4018, 4028, - 4023, 8023, 4025, 4027, 4030, 4037, 4033, 4039, 4040, 8023, - 4035, 8023, 4036, 4038, 4041, 4050, 4049, 4052, 4051, 4053, - 4056, 4059, 4063, 4066, 4074, 4076, 4072, 4067, 4079, 4071, - 4081, 4082, 4084, 4085, 4092, 4088, 4089, 4090, 8023, 4094, - 4095, 4096, 4097, 4103, 4104, 4106, 4107, 4112, 8023, 4114, - 8023, 4113, 4118, 4119, 4120, 4121, 4126, 4129, 4130, 4131, - 4134, 4138, 4137, 4139, 4140, 4147, 4141, 4144, 4145, 8023, - 4149, 4156, 4163, 4158, 4159, 4160, 4162, 4164, 4169, 4172, - - 8023, 4173, 4180, 4175, 4179, 4181, 4191, 4183, 4184, 4192, - 4195, 4186, 4187, 4193, 4199, 4200, 4202, 4201, 4203, 4204, - 4208, 4216, 4214, 4212, 4222, 4220, 4218, 4229, 4230, 4226, - 8023, 4235, 4231, 4237, 4238, 4239, 4240, 4241, 4243, 4246, - 4249, 4252, 4261, 4262, 4253, 4258, 4264, 4266, 4267, 4275, - 4270, 8023, 4282, 4268, 4283, 4278, 4280, 4287, 4281, 4288, - 4294, 4284, 4290, 4297, 4298, 4299, 4300, 4302, 4308, 4310, - 4317, 4312, 4303, 4314, 4316, 4327, 4318, 4319, 4322, 4328, - 8023, 4341, 4330, 4334, 4343, 4337, 4342, 4352, 4347, 4350, - 4351, 4353, 4354, 4359, 4355, 4360, 4362, 4363, 4366, 4369, - - 4374, 4364, 8023, 8023, 4377, 4371, 4378, 4380, 8023, 4383, - 4386, 4394, 4389, 4390, 4395, 4391, 4398, 4393, 4400, 4399, - 4403, 4401, 4416, 4419, 4402, 4404, 8023, 4429, 4408, 4430, - 4421, 4425, 4437, 4433, 8023, 4426, 4440, 4439, 4442, 4443, - 4436, 4444, 4446, 4450, 4448, 4454, 4449, 4455, 4458, 4462, - 4456, 4469, 4461, 4470, 4474, 4472, 4475, 4478, 8023, 4477, - 4479, 4480, 4484, 4486, 4487, 4488, 8023, 4489, 4491, 4493, - 4496, 4500, 4505, 4507, 4511, 4512, 4514, 4499, 4517, 4518, - 4519, 4521, 4522, 4525, 4532, 4529, 4533, 4530, 4527, 4539, - 4543, 4546, 8023, 4549, 4551, 4534, 4552, 4556, 8023, 4560, - - 4569, 4570, 8023, 4571, 4553, 4561, 4572, 4580, 8023, 4573, - 4577, 4575, 4582, 4576, 4592, 4578, 4594, 4589, 4590, 4597, - 4591, 4593, 4598, 4599, 8023, 4602, 4605, 4607, 8023, 4609, - 4615, 4616, 4620, 4621, 4626, 4629, 4627, 4628, 4636, 4631, - 4633, 4634, 4632, 8023, 4639, 4651, 8023, 4643, 4649, 4635, - 4647, 4652, 4654, 8023, 4657, 4658, 4660, 4662, 4663, 4666, - 4668, 4674, 4676, 4664, 4678, 4679, 4680, 4688, 4681, 4686, - 4689, 4690, 4692, 4693, 4695, 8023, 4702, 4694, 4696, 4698, - 4700, 4715, 4704, 4706, 4710, 4717, 4719, 8023, 8023, 4724, - 8023, 4725, 4721, 4726, 4727, 8023, 4729, 4733, 4736, 4734, - - 4738, 4746, 4735, 4750, 4740, 4753, 4754, 8023, 4760, 4763, - 8023, 4745, 4755, 4771, 4766, 4767, 4757, 4769, 4772, 4775, - 4770, 4778, 4781, 4777, 4782, 4783, 4786, 4785, 4802, 4787, - 4805, 8023, 4797, 4798, 4803, 4813, 4788, 4799, 4820, 4822, - 4825, 4829, 4814, 8023, 4830, 4816, 4831, 4832, 4833, 8023, - 8023, 4836, 8023, 4838, 4839, 8023, 4841, 4842, 4843, 4846, - 4847, 4857, 4850, 8023, 4852, 4855, 4859, 4860, 4863, 4864, - 8023, 4871, 4872, 4865, 4873, 4874, 4881, 4879, 4880, 4878, - 4888, 4889, 8023, 4885, 4892, 4895, 4899, 4900, 4902, 4896, - 4903, 4914, 4905, 4915, 4918, 4922, 4909, 4925, 4926, 4921, - - 4931, 4924, 4932, 4934, 4938, 4939, 4928, 8023, 4941, 4940, - 4948, 4942, 4957, 4943, 4953, 4954, 8023, 4958, 4960, 4959, - 4965, 8023, 4961, 4967, 4968, 4979, 4973, 4976, 4980, 4969, - 4981, 4982, 4984, 4983, 8023, 4989, 4990, 4992, 4995, 5003, - 5004, 4993, 8023, 8023, 5009, 8023, 5010, 4997, 5007, 5005, - 5014, 5017, 5019, 5021, 5025, 5027, 5029, 5031, 5032, 5033, - 5034, 5036, 8023, 5038, 5047, 5040, 5059, 5050, 5060, 5052, - 8023, 5043, 5061, 8023, 5063, 8023, 5042, 5064, 5067, 5069, - 5068, 5072, 5073, 5075, 5076, 5079, 8023, 5086, 5078, 5088, - 5091, 5089, 5097, 5100, 5101, 5109, 8023, 5110, 5092, 5111, - - 5102, 8023, 5104, 5113, 5105, 5116, 5117, 5119, 5120, 5121, - 5123, 5125, 5126, 5133, 5136, 5127, 5134, 5141, 5144, 5145, - 5146, 5147, 5149, 5151, 5150, 5153, 8023, 5157, 5155, 5156, - 5160, 5161, 5162, 5169, 5171, 5173, 5172, 5182, 5178, 5183, - 8023, 5180, 8023, 5181, 5189, 5190, 5197, 5191, 5201, 5202, - 5205, 5204, 5198, 5206, 5210, 5212, 5215, 5216, 5225, 5219, - 5221, 5226, 5227, 8023, 5230, 5232, 5235, 5237, 5240, 5242, - 5244, 5246, 8023, 5248, 5245, 5247, 5254, 5255, 8023, 5257, - 5259, 5260, 5262, 5263, 5270, 5271, 5272, 5274, 5276, 5264, - 5280, 5282, 5283, 5287, 5291, 5285, 5288, 8023, 5292, 5294, - - 5295, 5301, 5298, 5303, 5305, 5306, 5312, 5318, 5296, 5310, - 5319, 8023, 5320, 5322, 5324, 5332, 8023, 5327, 5329, 5330, - 5331, 5333, 5339, 5336, 5334, 5340, 5343, 5345, 5356, 5342, - 5350, 8023, 5362, 5352, 5363, 5364, 5366, 5367, 5358, 5369, - 5379, 5374, 5386, 5387, 8023, 5377, 5381, 5389, 5391, 5392, - 5398, 5399, 5382, 5400, 5401, 5402, 8023, 5408, 5410, 5411, - 5404, 5420, 5424, 5417, 5421, 5431, 5422, 5429, 5426, 5430, - 5432, 5433, 5437, 5439, 5440, 5441, 5442, 5458, 5460, 5455, - 8023, 5444, 8023, 5445, 5457, 5461, 5469, 5467, 5470, 5471, - 5474, 5477, 5475, 5472, 8023, 5479, 5482, 5485, 5486, 5487, - - 5488, 5491, 5500, 8023, 5490, 5493, 5489, 5503, 8023, 5507, - 5506, 5508, 5512, 5513, 5517, 5519, 5523, 5514, 5526, 8023, - 5530, 5532, 5531, 5539, 5543, 5538, 5541, 5542, 5544, 5546, - 5548, 5550, 5551, 5552, 5560, 5555, 5557, 8023, 5520, 5563, - 5568, 5571, 5572, 5565, 5573, 5559, 5580, 5586, 5575, 8023, - 5578, 5561, 5587, 5589, 5590, 5591, 5592, 5593, 5600, 5596, - 5605, 5603, 5610, 5597, 5599, 5601, 5614, 5613, 5617, 8023, - 5621, 5622, 5623, 5630, 5631, 5627, 5637, 8023, 5632, 8023, - 5626, 5629, 5644, 5646, 5647, 8023, 5650, 5636, 5652, 5642, - 5656, 8023, 8023, 5654, 5665, 5660, 5662, 5664, 5666, 8023, - - 8023, 5670, 8023, 5663, 8023, 5674, 5667, 8023, 8023, 5675, - 5676, 5677, 5679, 5682, 8023, 5684, 5685, 5687, 8023, 5692, - 8023, 5699, 5694, 5695, 5700, 5698, 5701, 8023, 5704, 5705, - 5707, 5709, 5711, 8023, 5712, 5713, 5718, 5731, 5715, 5717, - 8023, 5727, 5729, 5730, 5734, 5740, 5735, 5736, 5741, 5743, - 5744, 5745, 5748, 8023, 5753, 5756, 5757, 5749, 5759, 5747, - 5769, 5770, 5761, 5771, 5776, 5773, 5777, 5779, 5781, 5783, - 5780, 5790, 5792, 5794, 5784, 5798, 5787, 5801, 5802, 5807, - 5809, 5804, 5811, 5812, 5813, 5814, 5818, 5820, 5817, 5822, - 5826, 5827, 5829, 5830, 5832, 5837, 5823, 5840, 5841, 5844, - - 5847, 5848, 5851, 5852, 5853, 5854, 5855, 5856, 5859, 5860, - 5858, 5863, 5862, 5875, 5877, 5866, 5869, 8023, 5871, 5882, - 5883, 5885, 5888, 5891, 5892, 5893, 5894, 5896, 5898, 5903, - 5900, 5908, 8023, 8023, 8023, 5906, 5910, 8023, 5916, 5913, - 5918, 5919, 5920, 8023, 5921, 5922, 5923, 5924, 5926, 5925, - 5927, 5928, 5932, 5933, 5936, 5942, 8023, 5949, 5956, 5948, - 5937, 5957, 5961, 8023, 5958, 5964, 5950, 5965, 5969, 5970, - 5971, 5972, 5973, 5976, 5974, 5975, 5978, 5981, 5985, 5995, - 5980, 5989, 5996, 8023, 5998, 6004, 6005, 6001, 6006, 6008, - 6009, 6011, 6010, 6013, 6014, 6016, 6017, 6018, 6020, 6021, - - 6022, 6030, 6039, 6033, 6043, 8023, 6026, 6047, 8023, 6040, - 6044, 6048, 6050, 6051, 6053, 6054, 6057, 6055, 6058, 8023, - 8023, 6059, 6064, 6065, 6067, 6061, 6069, 6072, 6073, 6078, - 6081, 8023, 6080, 6083, 6086, 6090, 6089, 6091, 8023, 6096, - 6097, 6099, 6101, 6102, 6105, 6103, 6106, 6107, 6111, 6117, - 6108, 6123, 8023, 6120, 6124, 6131, 6136, 6139, 6126, 6141, - 6113, 6134, 6142, 6144, 6129, 6147, 8023, 6148, 8023, 8023, - 8023, 6150, 6152, 6153, 6155, 6157, 6159, 6160, 6162, 6165, - 6167, 6164, 6166, 6168, 8023, 6178, 8023, 8023, 6179, 8023, - 6180, 6181, 6182, 6188, 6189, 6190, 6192, 8023, 6191, 8023, - - 6193, 6197, 6194, 6204, 6211, 6207, 6201, 6213, 6205, 6215, - 6219, 6217, 6220, 6221, 6229, 6225, 6227, 6228, 8023, 6233, - 6231, 6235, 6237, 6244, 8023, 8023, 6245, 6241, 6247, 6249, - 6252, 6257, 6253, 6259, 6260, 6268, 6263, 6265, 6266, 6269, - 6272, 6273, 6275, 6282, 6283, 6279, 6280, 6286, 8023, 6288, - 6289, 6290, 8023, 6291, 8023, 6297, 6299, 6300, 6298, 6301, - 6306, 6308, 6309, 6311, 6318, 6313, 6319, 8023, 8023, 6312, - 6327, 6323, 8023, 8023, 6325, 6326, 6328, 6331, 6333, 6334, - 6335, 8023, 6336, 6338, 6339, 6337, 6342, 6343, 6356, 6349, - 8023, 6357, 8023, 6353, 8023, 6359, 6361, 6362, 6370, 6371, - - 8023, 6366, 6374, 6375, 6377, 6378, 6379, 6383, 8023, 6380, - 6381, 8023, 6390, 6393, 6391, 6382, 6397, 6399, 6401, 8023, - 6402, 6405, 6407, 6406, 8023, 6408, 6409, 6413, 6414, 6415, - 6418, 6419, 6426, 6428, 8023, 6430, 6431, 6432, 6434, 8023, - 6439, 8023, 6433, 6440, 6444, 6447, 6448, 8023, 6449, 6450, - 6451, 6454, 8023, 6458, 6462, 6464, 6465, 6459, 6466, 8023, - 6474, 6467, 8023, 6475, 6477, 6480, 6483, 6478, 6487, 6484, - 6488, 6489, 6496, 6492, 6494, 8023, 8023, 6505, 6507, 6508, - 6509, 123, 6517, 6500, 6501, 6512, 6513, 6524, 6526, 6528, - 6515, 6525, 6531, 8023, 8023, 6534, 6536, 6535, 8023, 6537, - - 6543, 8023, 6527, 6544, 6538, 6548, 6549, 6550, 6556, 6551, - 6553, 6558, 6559, 6561, 6560, 6562, 6569, 8023, 6576, 6584, - 6563, 6580, 6585, 6587, 6589, 6591, 6593, 6595, 6596, 6597, - 6598, 6599, 6600, 6602, 6604, 6603, 6605, 6606, 6612, 6613, - 6614, 8023, 6619, 6621, 6623, 6625, 6628, 6629, 6631, 6630, - 8023, 6638, 6639, 6642, 6644, 8023, 6651, 6643, 6645, 6656, - 6653, 6657, 8023, 6647, 6659, 6661, 6663, 6664, 6668, 6669, - 6670, 6671, 6678, 8023, 6675, 6674, 6679, 6681, 6682, 6689, - 6692, 6695, 6699, 6693, 8023, 6700, 8023, 8023, 8023, 6701, - 6703, 6705, 8023, 6710, 6707, 6711, 6712, 8023, 6714, 6717, - - 6718, 6726, 6722, 8023, 8023, 8023, 6723, 6724, 6728, 8023, - 6725, 6738, 8023, 6731, 8023, 6733, 8023, 6735, 6739, 6741, - 6746, 8023, 6747, 6749, 8023, 6750, 6751, 6753, 6756, 8023, - 6759, 6766, 6769, 6762, 6770, 6772, 6774, 6775, 6773, 8023, - 8023, 6782, 6780, 6781, 6783, 6785, 6777, 6787, 6789, 6791, - 6797, 6804, 8023, 6800, 6802, 8023, 6803, 6806, 6808, 6816, - 6805, 6812, 6814, 8023, 6818, 8023, 6820, 8023, 6809, 6821, - 6823, 6826, 6828, 6831, 6832, 6676, 6835, 6833, 6842, 6839, - 6843, 6841, 6845, 6846, 6849, 6856, 6852, 8023, 8023, 6866, - 6861, 8023, 6858, 6868, 6870, 8023, 6857, 8023, 6874, 8023, - - 6876, 6877, 8023, 6879, 6880, 6881, 8023, 8023, 6883, 6885, - 6888, 6895, 6887, 6891, 6894, 8023, 6898, 6900, 6901, 6902, - 6906, 6903, 6904, 6908, 6911, 6912, 6916, 6919, 8023, 6921, - 8023, 6920, 6930, 6926, 8023, 8023, 6927, 6928, 6936, 6938, - 6932, 6939, 6942, 6944, 6943, 6945, 6956, 6948, 6946, 6951, - 6963, 6964, 6973, 6953, 6957, 6974, 6975, 8023, 8023, 8023, - 6966, 6970, 6979, 6980, 6987, 6983, 6986, 8023, 6994, 6984, - 8023, 6991, 6993, 6995, 6997, 7004, 7001, 7006, 8023, 7003, - 7007, 7008, 7009, 7011, 7012, 7013, 7014, 8023, 7021, 7027, - 7035, 7032, 7024, 7036, 7040, 7043, 7045, 7046, 7028, 7048, - - 7017, 7050, 7057, 7053, 8023, 8023, 7060, 7052, 8023, 7062, - 7064, 8023, 8023, 7054, 8023, 7056, 7065, 7066, 7067, 7069, - 8023, 7072, 7074, 7075, 7077, 8023, 7079, 7081, 7083, 7084, - 7086, 7093, 7097, 7088, 7095, 7102, 7098, 7105, 8023, 7103, - 7116, 7111, 7113, 7112, 7114, 8023, 8023, 7115, 7123, 8023, - 7125, 7128, 7120, 7135, 7126, 7137, 7140, 7141, 8023, 7127, - 8023, 7144, 7149, 7130, 7142, 7151, 7143, 7152, 7153, 7157, - 8023, 7158, 7159, 7160, 7161, 8023, 7165, 7168, 7169, 7167, - 7170, 8023, 7172, 7173, 7182, 7174, 8023, 7185, 7189, 7190, - 8023, 8023, 8023, 7195, 7197, 7198, 8023, 8023, 8023, 7191, - - 7199, 8023, 7201, 7207, 7208, 7210, 8023, 7211, 8023, 8023, - 7214, 7218, 7222, 7224, 7231, 7217, 8023, 7225, 7232, 7234, - 7235, 7236, 8023, 7238, 7240, 8023, 7248, 7249, 7251, 7244, - 7247, 7255, 7256, 7258, 7259, 7261, 7263, 7264, 7265, 8023, - 8023, 7267, 7268, 7269, 7271, 7272, 8023, 7270, 7274, 7281, - 7284, 7289, 7290, 7294, 7296, 7300, 7297, 7301, 7302, 7303, - 7310, 7311, 7306, 7308, 7313, 7317, 7320, 7314, 7327, 7324, - 7329, 7337, 7339, 7328, 7340, 8023, 8023, 7342, 7330, 7347, - 8023, 7349, 7350, 8023, 7351, 8023, 7353, 7355, 7357, 7361, - 8023, 7363, 7365, 7367, 7371, 7332, 8023, 7368, 7373, 8023, - - 8023, 7374, 7375, 7376, 7378, 7381, 8023, 8023, 7384, 7379, - 7385, 7386, 8023, 7387, 7390, 7391, 7399, 7392, 7400, 7403, - 7404, 7408, 7412, 8023, 7401, 7418, 8023, 8023, 8023, 7409, - 7419, 7421, 7422, 7425, 7423, 8023, 7427, 7434, 7429, 7431, - 7432, 7435, 7433, 8023, 7438, 7445, 8023, 8023, 7442, 7440, - 8023, 7456, 8023, 8023, 7439, 7447, 8023, 8023, 8023, 8023, - 8023, 8023, 8023, 8023, 7458, 7459, 8023, 7452, 7460, 7464, - 7468, 7470, 7473, 8023, 7471, 7475, 7477, 7479, 8023, 7481, - 8023, 7472, 7483, 7482, 7485, 7488, 8023, 7493, 8023, 7500, - 7496, 7497, 7499, 7509, 7498, 7501, 7510, 7506, 7512, 7515, - - 7514, 7517, 7518, 7516, 7521, 7520, 7522, 7524, 7533, 7536, - 7537, 7538, 7540, 7543, 7544, 7546, 7547, 7548, 7545, 8023, - 8023, 8023, 8023, 7549, 7554, 7559, 7560, 7567, 7562, 7566, - 7572, 7576, 7578, 7579, 7580, 7581, 7582, 7583, 7585, 7586, - 7595, 7590, 7591, 7592, 7594, 7596, 7606, 7608, 7612, 8023, - 7614, 7615, 7617, 8023, 7619, 7602, 7624, 7627, 7621, 7609, - 7630, 8023, 7631, 7632, 8023, 7633, 7634, 8023, 8023, 7638, - 7639, 7641, 7635, 7648, 7650, 7645, 7647, 7651, 7653, 7656, - 8023, 7662, 8023, 8023, 8023, 8023, 7663, 7664, 8023, 7665, - 8023, 8023, 7666, 7668, 8023, 7667, 7672, 7669, 7673, 8023, - - 7674, 7684, 7676, 7683, 7686, 7682, 7692, 7693, 7691, 8023, - 8023, 7700, 7702, 7704, 7705, 7706, 7707, 8023, 7703, 7709, - 7710, 7717, 7713, 7727, 7728, 7729, 7716, 7736, 8023, 7718, - 7719, 7737, 7743, 7740, 7747, 7731, 8023, 7744, 7750, 7751, - 7752, 7753, 7760, 7755, 7757, 7762, 7764, 7766, 8023, 7767, - 8023, 7773, 7776, 7777, 7779, 7780, 7781, 7782, 7787, 7785, - 8023, 8023, 8023, 7783, 7793, 8023, 7791, 7801, 7792, 7803, - 7805, 7807, 7808, 7794, 7810, 7819, 7816, 7820, 7824, 7825, - 7826, 7827, 7829, 7828, 8023, 8023, 7831, 7835, 8023, 7836, - 7837, 7838, 7839, 7843, 8023, 7849, 7840, 7845, 7850, 7853, - - 7855, 8023, 7861, 7866, 7856, 8023, 7867, 8023, 8023, 7868, - 7869, 7870, 7875, 7877, 8023, 8023, 8023, 7903, 7910, 7917, - 7924, 7931, 7938, 7945, 88, 7952, 7959, 7966, 7973, 7980, - 7987, 7994, 8001, 8008, 8015 + 998, 986, 993, 1001, 1023, 1019, 1002, 1009, 1003, 1020, + 1021, 1028, 1036, 1031, 1033, 1034, 1037, 1035, 1038, 1045, + 1040, 895, 1047, 1060, 1041, 1044, 1050, 1051, 1048, 1068, + 1054, 1069, 1073, 1074, 1075, 1063, 1079, 1080, 1081, 1083, + 1092, 1115, 1090, 1086, 1098, 1087, 1102, 1110, 1085, 1107, + 1105, 1116, 1117, 1088, 1123, 1118, 1126, 1121, 1130, 1134, + 1137, 1145, 1141, 1144, 1127, 1143, 1149, 1150, 1151, 1153, + 1156, 1157, 1158, 1163, 1161, 1162, 1167, 1169, 1168, 1177, + + 1178, 1179, 1182, 1171, 1184, 1188, 8183, 1195, 1193, 8183, + 1191, 1196, 1197, 1198, 1199, 1200, 1201, 1202, 8183, 1206, + 1209, 1203, 1217, 1208, 1219, 1215, 1216, 1235, 1228, 1230, + 1232, 1236, 1237, 1238, 1241, 1248, 1245, 1246, 1258, 1247, + 1254, 1255, 1257, 1256, 1262, 1263, 1266, 1264, 1267, 1270, + 1271, 1290, 8183, 1272, 1273, 1280, 1282, 1274, 1297, 1285, + 1299, 1308, 1300, 1307, 1305, 1311, 1325, 1314, 1322, 1323, + 1327, 1328, 1287, 1331, 1333, 1336, 1335, 1339, 1337, 1341, + 1343, 1344, 1349, 1346, 1357, 1345, 1353, 1359, 8183, 1360, + 1361, 1363, 1369, 1377, 1374, 1375, 1376, 1378, 1385, 1381, + + 1380, 1383, 1384, 1389, 1382, 1393, 1400, 1394, 1402, 1409, + 1410, 1405, 1408, 1407, 1412, 1413, 1415, 1420, 1416, 1422, + 1424, 1436, 1426, 1429, 1433, 1444, 1443, 1446, 1448, 1455, + 1457, 1450, 1452, 1453, 1458, 1454, 1460, 1462, 1463, 1464, + 1467, 1472, 1471, 1480, 1476, 1477, 1482, 1478, 1484, 1485, + 1487, 1488, 1489, 1492, 1497, 1495, 1499, 1501, 1503, 1516, + 1504, 1507, 1505, 1510, 1520, 1529, 1518, 1521, 8183, 1530, + 1537, 1535, 1538, 1539, 1540, 1542, 1545, 1546, 1550, 1549, + 1553, 1552, 1555, 1556, 1554, 1558, 1562, 1563, 1564, 1572, + 1569, 1573, 1575, 1578, 1580, 1581, 1591, 1586, 1595, 1599, + + 1584, 1601, 1583, 1602, 1603, 1605, 1606, 1607, 1614, 1610, + 1618, 1613, 1609, 1622, 1621, 1629, 1625, 1624, 1631, 1630, + 1644, 1641, 1632, 1633, 1645, 1646, 1652, 1648, 1654, 1657, + 1665, 1658, 1667, 1674, 1676, 1669, 1512, 1671, 1678, 1679, + 1681, 1683, 1684, 1685, 1686, 1693, 1688, 1689, 1695, 1696, + 1691, 1697, 1705, 1703, 1713, 1712, 1714, 1715, 1719, 1720, + 1721, 1722, 1724, 1723, 1725, 1729, 1730, 1731, 1733, 1746, + 1745, 1734, 1753, 1747, 1736, 1754, 1756, 1758, 1760, 1762, + 1764, 1766, 1767, 1768, 1771, 1769, 1774, 1775, 1782, 1783, + 1784, 1785, 1788, 1786, 1789, 1791, 1805, 1792, 1801, 1806, + + 1807, 1808, 1809, 1811, 1812, 1813, 1816, 1818, 1829, 1820, + 1822, 8183, 1830, 1838, 1833, 1835, 1836, 1839, 1837, 1841, + 1848, 1850, 1845, 1843, 1847, 1846, 1856, 1857, 1882, 8183, + 1860, 8183, 8183, 1866, 1861, 8183, 8183, 1865, 1867, 8183, + 1868, 1870, 1871, 1869, 1879, 1888, 1892, 1886, 1895, 1896, + 1898, 1905, 1919, 1907, 1903, 1909, 1906, 1911, 1912, 1925, + 1917, 1914, 1934, 1928, 1916, 1932, 1948, 1944, 1949, 1946, + 1952, 1953, 1955, 1956, 1958, 1965, 1966, 1962, 1967, 1969, + 1970, 1971, 1975, 1972, 1976, 1978, 1979, 1981, 1982, 1984, + 1985, 1987, 1996, 1998, 2000, 2007, 2014, 8183, 2010, 2017, + + 2016, 2001, 2004, 1992, 2020, 2027, 2024, 2028, 2030, 2025, + 2032, 2036, 2038, 2026, 2039, 2041, 2043, 2042, 2045, 2049, + 2050, 2051, 2054, 2055, 2057, 2061, 2062, 2058, 2063, 8183, + 2068, 2069, 2071, 2072, 2073, 2074, 2075, 2078, 2079, 2080, + 2091, 2095, 2085, 2086, 2092, 2093, 2108, 2096, 2103, 2105, + 2109, 2112, 2113, 2114, 2115, 8183, 2117, 2123, 2124, 2125, + 2127, 2129, 2116, 2131, 2133, 2138, 2135, 2139, 2142, 2141, + 2147, 2149, 2152, 2153, 2140, 2150, 2154, 2157, 2164, 2160, + 2170, 2177, 2167, 2171, 2173, 2178, 2179, 2180, 2181, 2183, + 2184, 2188, 2189, 2196, 2199, 2192, 2210, 2197, 2194, 2213, + + 2218, 2215, 2202, 2216, 2217, 2220, 2223, 2225, 2232, 2235, + 2227, 2231, 2234, 2243, 2239, 2238, 2245, 2242, 2240, 2246, + 2252, 2262, 2250, 2259, 2266, 2254, 2257, 2264, 2269, 2271, + 8183, 2272, 2273, 2275, 8183, 2280, 2281, 2282, 2304, 2283, + 2284, 2291, 2297, 2299, 2286, 2314, 2302, 2306, 2292, 2294, + 2300, 2316, 2329, 2317, 2324, 2327, 2332, 2334, 2333, 2336, + 2337, 2353, 2340, 2342, 2346, 2354, 2344, 2357, 2364, 2366, + 2368, 2370, 2369, 2371, 2372, 2374, 2394, 2373, 2375, 2376, + 2377, 2378, 2381, 2388, 2383, 2382, 2387, 2384, 2399, 2405, + 2410, 2406, 2407, 2409, 2412, 2415, 2416, 2423, 2425, 2417, + + 8183, 2430, 2432, 2426, 2431, 2438, 2446, 2439, 2441, 8183, + 2443, 2447, 2442, 2454, 2449, 2450, 2453, 2457, 2455, 2463, + 2464, 2461, 2466, 2467, 2471, 2468, 2469, 2482, 2479, 8183, + 2484, 8183, 2485, 2487, 2488, 2490, 2491, 2498, 2493, 2494, + 2495, 2501, 2502, 2503, 2505, 8183, 8183, 2506, 2516, 2514, + 2524, 2526, 2528, 2518, 2529, 2530, 8183, 2531, 2538, 8183, + 2535, 2533, 2542, 2540, 2541, 2546, 2549, 2550, 2552, 2497, + 2555, 2556, 2553, 2557, 2565, 2558, 2573, 2560, 2576, 2570, + 8183, 2579, 2582, 2562, 2586, 2587, 2577, 2588, 2589, 2590, + 2596, 8183, 2598, 2599, 2600, 2601, 2609, 2611, 2605, 2602, + + 2613, 2617, 2607, 2612, 2619, 2621, 2623, 2632, 2633, 2634, + 2630, 2637, 2644, 2640, 2647, 8183, 2643, 2646, 2629, 2656, + 2652, 2654, 2651, 2658, 2659, 2655, 2661, 2662, 2669, 2670, + 2663, 2671, 2665, 2675, 2677, 2684, 2686, 2682, 2685, 2689, + 2691, 2692, 2699, 2695, 2694, 2702, 2700, 2704, 2701, 2705, + 2703, 8183, 2708, 2714, 2716, 2711, 2717, 2721, 2724, 216, + 2725, 2730, 2729, 2731, 2733, 2732, 2735, 2737, 2746, 2749, + 2748, 2738, 2750, 2754, 2758, 2762, 2751, 2755, 2763, 2761, + 2752, 2770, 2772, 2774, 2764, 8183, 2778, 2780, 2781, 2775, + 2782, 2792, 2787, 2790, 2788, 2793, 8183, 2791, 2803, 2801, + + 2811, 2813, 2805, 2814, 2816, 2815, 2799, 2821, 8183, 2822, + 2823, 2824, 2831, 2832, 2826, 2833, 2829, 8183, 2839, 2841, + 2845, 2835, 2847, 2849, 2851, 2843, 2854, 2856, 2859, 2857, + 2861, 2864, 2863, 2865, 2866, 2867, 2870, 2877, 2880, 2878, + 2881, 2883, 2879, 2887, 2890, 2889, 2891, 2895, 2903, 2893, + 8183, 2911, 2900, 2904, 2909, 2907, 2896, 2914, 2920, 2929, + 2921, 2922, 2924, 2925, 2941, 2931, 2930, 2935, 2945, 2947, + 2951, 2934, 2952, 2959, 2957, 2958, 2965, 2955, 2967, 2968, + 2970, 2972, 2978, 2974, 2985, 2987, 2980, 2982, 2984, 2989, + 2990, 2991, 2994, 3003, 2998, 3006, 3002, 3010, 3008, 3011, + + 3013, 3001, 3016, 3026, 3019, 8183, 3028, 3022, 3033, 3034, + 3035, 3039, 3041, 3048, 3036, 3043, 3045, 3046, 3050, 3051, + 3056, 3058, 3059, 3060, 3063, 3064, 3071, 3066, 3069, 3075, + 3070, 3080, 3074, 3077, 3087, 3089, 3076, 3090, 3092, 3093, + 3097, 3098, 3100, 8183, 3106, 3099, 3105, 3110, 3112, 3113, + 3115, 3116, 3118, 3120, 3121, 3122, 3126, 3127, 3128, 3129, + 3130, 3137, 3134, 3135, 3136, 3140, 8183, 3146, 3148, 3152, + 3153, 3154, 3155, 3156, 3157, 3163, 3170, 3171, 3174, 3172, + 3160, 3179, 3180, 3181, 8183, 3188, 3189, 3190, 3192, 3193, + 3201, 3196, 3184, 3199, 3206, 3209, 3200, 3202, 8183, 3211, + + 3186, 2185, 3212, 3213, 3214, 3221, 3223, 3218, 3219, 8183, + 3231, 3226, 3228, 3229, 3238, 3235, 3239, 3236, 3241, 3243, + 3245, 3247, 3249, 3252, 3253, 3261, 3254, 3258, 8183, 3256, + 3262, 3266, 3270, 3268, 3273, 3274, 3280, 3278, 3281, 3282, + 3285, 3289, 3162, 3287, 8183, 3305, 3294, 3302, 3284, 3309, + 3304, 3307, 3311, 3312, 3313, 3314, 3316, 3315, 3320, 3321, + 8183, 3322, 3324, 3326, 3327, 3339, 3330, 3331, 3338, 3337, + 3340, 3345, 3346, 3347, 3351, 3352, 3353, 3354, 3363, 3355, + 3365, 3367, 3357, 3374, 3369, 3375, 3376, 3377, 3380, 3388, + 3392, 3384, 3393, 3396, 3399, 3387, 3389, 3401, 3408, 3413, + + 3415, 3411, 3416, 8183, 3419, 3400, 3414, 3421, 3420, 3426, + 3422, 3424, 3427, 3425, 3433, 3435, 3442, 3430, 3434, 3449, + 3452, 3450, 3455, 3456, 3458, 3459, 3460, 3461, 3468, 3463, + 3464, 3465, 3470, 3473, 3471, 3480, 3472, 3479, 3481, 3484, + 3486, 3493, 3491, 3492, 3500, 3495, 3497, 3501, 3502, 3503, + 3504, 3505, 3507, 3509, 3515, 3508, 3513, 3517, 3518, 3526, + 3534, 3535, 3527, 3529, 3537, 3538, 3541, 8183, 8183, 3543, + 8183, 3550, 3539, 3546, 3553, 3548, 3555, 3558, 3559, 3561, + 3566, 3563, 3575, 3567, 3570, 3578, 3571, 3580, 3581, 3574, + 3586, 3587, 3588, 3595, 3591, 8183, 3592, 8183, 3599, 3597, + + 3598, 3600, 3611, 3602, 8183, 3607, 8183, 3609, 3614, 3615, + 3616, 3617, 8183, 3620, 3619, 3621, 3625, 3624, 3626, 3628, + 3629, 3630, 3636, 3637, 3638, 3645, 3646, 3648, 3635, 3654, + 3655, 3656, 3658, 3660, 3661, 3662, 3663, 3665, 3666, 3668, + 3671, 3673, 3675, 3677, 3681, 3682, 3683, 3684, 3685, 8183, + 3691, 3700, 3695, 3701, 3703, 3704, 3706, 3707, 3709, 3711, + 3687, 3710, 3715, 3713, 3717, 3722, 3723, 3730, 3726, 3732, + 3735, 3734, 3736, 3738, 3741, 3748, 3747, 3755, 3752, 8183, + 3750, 3754, 3751, 3758, 3760, 3762, 8183, 3761, 3769, 3759, + 3771, 3775, 3773, 3763, 3778, 3779, 3784, 3780, 3788, 3786, + + 3789, 3790, 3797, 3794, 3801, 8183, 3796, 3803, 3809, 3810, + 3812, 3814, 3821, 3822, 3818, 3824, 3826, 3835, 3828, 3817, + 3819, 3831, 3832, 3836, 3846, 3847, 3848, 3844, 3851, 3843, + 3853, 3855, 3856, 3857, 3859, 3862, 3860, 3863, 3864, 3867, + 3869, 3871, 3868, 3865, 3870, 3887, 3872, 3873, 8183, 3876, + 3892, 3893, 3900, 3895, 3896, 3897, 3899, 3898, 3902, 3905, + 8183, 3908, 3909, 3911, 3910, 3920, 3918, 3923, 3924, 3925, + 3926, 3928, 3930, 3927, 3938, 3936, 8183, 3939, 8183, 3940, + 3932, 3953, 3961, 3963, 3955, 3951, 3964, 3965, 3966, 3971, + 3972, 3974, 3975, 3977, 3978, 3976, 3982, 3984, 3986, 3987, + + 3988, 3989, 3990, 3996, 3992, 4001, 4013, 4000, 4011, 3995, + 4012, 4014, 4017, 4019, 4027, 4023, 4022, 8183, 8183, 4020, + 4024, 4029, 4033, 4037, 4038, 4039, 4048, 4043, 4046, 4051, + 4056, 4057, 4059, 4050, 4064, 4065, 4072, 8183, 4067, 4069, + 4070, 4073, 4074, 4082, 4075, 4080, 4095, 4086, 4087, 4096, + 4094, 8183, 4077, 4098, 4099, 4108, 4103, 4106, 4110, 8183, + 3941, 8183, 4105, 4107, 4111, 4112, 4114, 4122, 4121, 4123, + 4125, 4127, 4128, 4136, 4117, 4139, 4143, 4144, 4140, 4146, + 4148, 4149, 4150, 4152, 4158, 4160, 4155, 4156, 4161, 8183, + 4163, 4164, 4166, 4165, 4173, 4174, 4175, 4176, 4182, 4183, + + 4186, 8183, 4187, 8183, 4188, 4189, 4193, 4192, 4197, 4203, + 4200, 4205, 4207, 4209, 4210, 4211, 4213, 4216, 4214, 4218, + 4222, 4223, 8183, 4227, 4224, 4235, 4236, 4231, 4232, 4240, + 4234, 4241, 4251, 8183, 4242, 4258, 4245, 4253, 4254, 4263, + 4256, 4259, 4264, 4265, 4267, 4269, 4272, 4274, 4273, 4275, + 4276, 4277, 4279, 4281, 4283, 4284, 4282, 4295, 4296, 4297, + 4299, 4309, 4304, 8183, 4305, 4308, 4310, 4314, 4311, 4313, + 4318, 4316, 4320, 4323, 4324, 4336, 4337, 4326, 4328, 4333, + 4340, 4341, 4348, 4343, 8183, 4356, 4351, 4358, 4353, 4355, + 4357, 4359, 4360, 4366, 4361, 4367, 4371, 4368, 4373, 4374, + + 4375, 4377, 4382, 4391, 4386, 4388, 4389, 4390, 4401, 4392, + 4393, 4396, 4397, 8183, 4415, 4404, 4406, 4417, 4411, 4416, + 4426, 4423, 4424, 4425, 4427, 4429, 4430, 4428, 4434, 4435, + 4436, 4438, 4440, 4441, 4451, 4453, 4443, 8183, 8183, 4455, + 4445, 4456, 4457, 4465, 8183, 4459, 4467, 4475, 4471, 4472, + 4473, 4476, 4480, 4478, 4479, 4481, 4486, 4485, 4482, 4483, + 4498, 4487, 4495, 8183, 4505, 4501, 4509, 4502, 4507, 4510, + 4515, 8183, 4512, 4524, 4520, 4516, 4523, 4525, 4526, 4528, + 4527, 4529, 4533, 4534, 4535, 4537, 4539, 4542, 4550, 4545, + 4548, 4559, 4551, 4554, 4556, 8183, 4555, 4558, 4563, 4565, + + 4566, 4567, 4570, 8183, 4572, 4573, 4578, 4581, 4574, 4589, + 4584, 4592, 4594, 4598, 4582, 4595, 4599, 4601, 4600, 4602, + 4604, 4613, 4608, 4612, 4611, 4615, 4630, 4631, 4617, 8183, + 4614, 4619, 4625, 4633, 4634, 4643, 8183, 4645, 4652, 4654, + 8183, 4655, 4635, 4657, 4647, 4656, 8183, 4658, 4660, 4663, + 4665, 4666, 4669, 4678, 4671, 4679, 4674, 4675, 4676, 4683, + 4680, 4684, 4686, 4685, 8183, 4688, 4687, 4696, 8183, 4703, + 4637, 4707, 4710, 4711, 4714, 4698, 4705, 4695, 4722, 4717, + 4719, 4721, 4725, 8183, 4726, 4736, 8183, 4729, 4733, 4718, + 4728, 4738, 4741, 8183, 4743, 4744, 4745, 4747, 4748, 4749, + + 4758, 4759, 4752, 4760, 4761, 4764, 4765, 4772, 4767, 4768, + 4775, 4774, 4776, 4777, 4779, 8183, 4786, 4778, 4781, 4788, + 4783, 4799, 4801, 4794, 4791, 4802, 4804, 8183, 8183, 4809, + 8183, 4811, 4789, 4813, 4815, 8183, 4818, 4816, 4825, 4820, + 4821, 4824, 4827, 4828, 4832, 4836, 4838, 8183, 4840, 4842, + 8183, 4844, 4845, 4853, 4848, 4849, 4852, 4855, 4857, 4859, + 4861, 4854, 4864, 4863, 4865, 4869, 4870, 4871, 4889, 4873, + 4891, 8183, 4872, 4880, 4887, 4885, 4890, 4881, 4902, 4904, + 4906, 4912, 4898, 4900, 4914, 8183, 4915, 4916, 4917, 4921, + 4922, 8183, 8183, 4923, 8183, 4924, 4928, 4930, 8183, 4925, + + 4931, 4936, 4938, 4940, 4947, 4943, 4945, 8183, 4944, 4948, + 4950, 4951, 4952, 4954, 8183, 4961, 4967, 4958, 4968, 4959, + 4975, 4973, 4970, 4980, 4988, 4981, 8183, 4971, 4984, 4985, + 4994, 4995, 4991, 4999, 5000, 5007, 5003, 5004, 5011, 5015, + 5010, 5018, 5019, 5016, 5022, 5017, 5025, 5030, 5027, 5033, + 5023, 8183, 5035, 5034, 5040, 5037, 5050, 5045, 5047, 5048, + 8183, 5051, 5053, 5054, 5061, 8183, 5055, 5062, 5063, 5074, + 5067, 5069, 5071, 5075, 5052, 5076, 5078, 5079, 8183, 5080, + 5083, 5081, 5097, 5094, 5098, 5100, 5086, 8183, 8183, 5102, + 8183, 5105, 5106, 5107, 5110, 5088, 5114, 5116, 5117, 5112, + + 5119, 5120, 5124, 5127, 5130, 5132, 5133, 5134, 5136, 8183, + 5139, 5146, 5137, 5154, 5150, 5157, 5152, 8183, 5160, 5141, + 8183, 5142, 8183, 5163, 5164, 5166, 5169, 5167, 5172, 5173, + 5175, 5178, 5177, 8183, 5185, 5188, 5180, 5189, 5181, 5190, + 5193, 5197, 5204, 8183, 5201, 5206, 5207, 5208, 8183, 5209, + 5210, 5212, 5214, 5213, 5216, 5218, 5217, 5219, 5220, 5222, + 5224, 5237, 5227, 5238, 5230, 5232, 5245, 5240, 5246, 5249, + 5247, 5250, 5256, 8183, 5251, 5253, 5257, 5261, 5262, 5264, + 5267, 5266, 5269, 5270, 5277, 5273, 5284, 8183, 5274, 8183, + 5279, 5283, 5290, 5293, 5294, 5299, 5300, 5301, 5302, 5303, + + 5306, 5308, 5309, 5312, 5316, 5323, 5313, 5317, 5324, 5325, + 8183, 5331, 5333, 5335, 5338, 5336, 5341, 5343, 5344, 8183, + 5346, 5347, 5352, 5307, 5353, 8183, 5355, 5354, 5357, 5359, + 5360, 5362, 5364, 5370, 5365, 5371, 8183, 5374, 5378, 5375, + 5381, 5383, 5384, 5387, 5392, 5386, 5388, 5393, 5394, 8183, + 5396, 5399, 5400, 5406, 5402, 5409, 5410, 5408, 5417, 5422, + 5412, 5415, 5423, 8183, 5424, 5426, 5428, 5435, 8183, 5432, + 5434, 5436, 5438, 5437, 5443, 5444, 5440, 5446, 5450, 5447, + 5458, 5454, 5456, 8183, 5465, 5448, 5467, 5462, 5472, 5473, + 5479, 5475, 5480, 5483, 5482, 5485, 8183, 5493, 5486, 5495, + + 5497, 5499, 5489, 5496, 5506, 5507, 5508, 5510, 8183, 5512, + 5515, 5518, 5511, 5525, 5528, 5521, 5524, 5535, 5532, 5533, + 8183, 5530, 5531, 5540, 5534, 5541, 5547, 5548, 5549, 5545, + 5552, 5566, 5561, 8183, 5551, 5553, 8183, 5562, 5563, 5567, + 5570, 5574, 5579, 5576, 5578, 5577, 5584, 5588, 5581, 8183, + 5589, 5590, 5592, 5594, 5595, 5598, 5600, 5597, 8183, 5599, + 5596, 5610, 5614, 8183, 5613, 5615, 5617, 5618, 5619, 5622, + 5624, 5629, 5630, 5632, 8183, 5635, 5636, 5638, 5646, 5647, + 5642, 5645, 5648, 5652, 5649, 5654, 5656, 5657, 5658, 5666, + 5663, 5664, 8183, 5667, 5665, 5673, 5674, 5675, 5678, 5681, + + 5682, 5684, 5686, 5683, 8183, 5689, 5691, 5692, 5693, 5695, + 5697, 5698, 5699, 5706, 5708, 5715, 5705, 5719, 5703, 5707, + 5717, 5722, 5723, 5725, 8183, 5728, 5729, 5730, 5737, 5738, + 5733, 5746, 8183, 5734, 8183, 5739, 5742, 5749, 5751, 5757, + 8183, 5752, 5747, 5760, 5759, 5764, 8183, 8183, 5766, 5767, + 5768, 5772, 5769, 5774, 5773, 5776, 8183, 8183, 5787, 8183, + 5775, 8183, 5777, 5781, 8183, 8183, 5784, 5788, 5794, 5790, + 5792, 8183, 5796, 5798, 5799, 5800, 5802, 8183, 5807, 8183, + 5809, 5810, 5815, 5812, 5817, 5818, 8183, 5819, 5821, 5820, + 5825, 5827, 8183, 5829, 5831, 5835, 5842, 5833, 5834, 8183, + + 5844, 5846, 5847, 5850, 5852, 5848, 5857, 5859, 5858, 5860, + 5861, 5865, 8183, 5868, 5871, 5873, 5866, 5876, 5862, 5877, + 5886, 5887, 5889, 5890, 5891, 5874, 5892, 5893, 5900, 5895, + 5905, 5907, 5909, 5911, 5913, 5914, 5916, 5917, 5919, 5924, + 5922, 5926, 5927, 5928, 5929, 5931, 5936, 5930, 5938, 5941, + 5933, 5943, 5945, 5951, 5952, 5953, 5954, 5955, 5956, 5961, + 5962, 5963, 5966, 5967, 5968, 5969, 5970, 5972, 5977, 5980, + 5979, 5974, 5985, 5990, 5997, 5992, 5984, 5995, 8183, 6000, + 5981, 6004, 6006, 6008, 6005, 6009, 6013, 6014, 6015, 6017, + 6022, 6023, 6024, 8183, 8183, 8183, 6029, 6030, 8183, 6032, + + 6034, 6036, 6037, 6039, 8183, 6040, 6041, 6042, 6043, 6045, + 6044, 6046, 6048, 6049, 6055, 6057, 6061, 8183, 6067, 6077, + 6058, 6068, 6070, 6081, 8183, 6074, 6085, 6078, 6082, 6086, + 6087, 6088, 6089, 6091, 6092, 6093, 6095, 6097, 6098, 6111, + 6114, 6102, 6106, 6115, 8183, 6117, 6119, 6126, 6123, 6125, + 6127, 6128, 6130, 6129, 6132, 6133, 6135, 6136, 6137, 6138, + 6139, 6140, 6150, 6158, 6160, 6164, 8183, 6146, 6167, 6151, + 6169, 8183, 6171, 6154, 6172, 6161, 6174, 6176, 6177, 6178, + 6182, 6185, 6186, 6188, 8183, 8183, 6189, 6192, 6191, 6196, + 6193, 6198, 6200, 6201, 6202, 6211, 8183, 6203, 6204, 6214, + + 6221, 6223, 6213, 8183, 6224, 6227, 6228, 6230, 6231, 6232, + 6233, 6234, 6235, 6238, 6241, 6236, 6253, 8183, 6242, 6250, + 6258, 6260, 6264, 6246, 6267, 6268, 6269, 6270, 6271, 6272, + 6275, 8183, 6276, 8183, 8183, 8183, 6279, 6281, 6277, 6285, + 6282, 6287, 6288, 6289, 6293, 6294, 6305, 6291, 6306, 8183, + 6308, 8183, 8183, 6309, 8183, 6310, 6312, 6313, 6316, 6317, + 6319, 6322, 8183, 6320, 6323, 8183, 6327, 6329, 6325, 6338, + 6344, 6331, 6341, 6333, 6345, 6339, 6353, 6347, 6355, 6349, + 6356, 6363, 6359, 6361, 6362, 8183, 6368, 6365, 6370, 6372, + 6378, 8183, 8183, 6379, 6373, 6381, 6383, 6385, 6393, 6389, + + 6391, 6390, 6403, 6398, 6400, 6401, 6399, 6407, 6409, 6410, + 6418, 6419, 6411, 6414, 6421, 8183, 6423, 6424, 6425, 8183, + 6415, 8183, 6432, 6433, 6434, 6435, 6436, 6441, 6442, 6443, + 6445, 6448, 6446, 6455, 8183, 8183, 6447, 6462, 6457, 8183, + 8183, 6458, 6459, 6461, 6464, 6467, 6468, 6469, 8183, 6471, + 6473, 6484, 6472, 6486, 6474, 6491, 6478, 8183, 6492, 8183, + 6476, 8183, 6498, 8183, 6499, 6494, 6500, 6508, 6510, 8183, + 6505, 6509, 6512, 6514, 6521, 6517, 6518, 6506, 6523, 8183, + 6520, 6519, 8183, 6536, 6534, 6535, 6522, 6533, 6542, 6538, + 8183, 6543, 6545, 6546, 6548, 8183, 6549, 6554, 6552, 6555, + + 6558, 6557, 6559, 6565, 6570, 8183, 6572, 6574, 6575, 6567, + 8183, 6584, 8183, 6573, 6581, 6579, 6595, 6585, 8183, 6587, + 6588, 6590, 6598, 8183, 6601, 6603, 6605, 6606, 6611, 6612, + 8183, 6614, 6615, 8183, 6596, 6618, 6619, 6622, 6623, 6627, + 6628, 6629, 6630, 6632, 6640, 6636, 6639, 8183, 8183, 6637, + 6651, 6646, 6648, 6653, 123, 6660, 6652, 6656, 6661, 6662, + 6669, 6670, 6671, 6655, 6673, 6667, 8183, 8183, 6679, 6682, + 6683, 8183, 6684, 6685, 8183, 6672, 6686, 6693, 6691, 6695, + 6696, 6699, 6701, 6702, 6704, 6705, 6707, 6706, 6711, 6715, + 8183, 6728, 6732, 6717, 6713, 6724, 6733, 6737, 6739, 6741, + + 6729, 6743, 6735, 6744, 6747, 6746, 6749, 6752, 6750, 6754, + 6751, 6758, 6761, 6762, 8183, 6765, 6767, 6768, 6772, 6774, + 6777, 6775, 6776, 8183, 6785, 6779, 6789, 6790, 6791, 8183, + 6793, 6795, 6797, 6799, 6800, 8183, 8183, 6801, 8183, 6802, + 6808, 6813, 6814, 6815, 6803, 6805, 6817, 6819, 6827, 8183, + 6823, 6825, 6828, 6829, 6831, 6837, 6840, 6830, 6841, 6842, + 8183, 6847, 8183, 8183, 8183, 6848, 6850, 6851, 8183, 6855, + 6852, 6856, 6858, 8183, 6860, 6864, 6861, 6873, 6868, 8183, + 8183, 8183, 6869, 6872, 6874, 8183, 6871, 6884, 8183, 6875, + 8183, 6879, 8183, 6885, 6888, 6895, 8183, 6889, 8183, 6892, + + 6899, 6901, 8183, 6902, 6903, 6905, 6906, 8183, 6909, 6912, + 6918, 6914, 6920, 6921, 6924, 6925, 6922, 8183, 8183, 6932, + 6929, 6930, 6931, 6934, 6937, 6938, 6939, 6942, 6945, 6952, + 8183, 6948, 6954, 8183, 6882, 6951, 6957, 6958, 6949, 6961, + 6964, 8183, 6965, 8183, 6967, 8183, 6969, 6970, 6971, 6974, + 6972, 6975, 6977, 6980, 6987, 6986, 6989, 6990, 6993, 6995, + 6997, 6998, 7000, 7003, 7007, 8183, 8183, 7014, 7005, 8183, + 7011, 7021, 7023, 8183, 7009, 8183, 7012, 7029, 8183, 7016, + 7018, 8183, 7031, 7025, 7033, 8183, 8183, 7040, 7035, 7037, + 7048, 7043, 7045, 7049, 8183, 7050, 7047, 7052, 7053, 7056, + + 7057, 7059, 7063, 7054, 7058, 7060, 7070, 8183, 7082, 8183, + 7065, 7083, 7081, 8183, 8183, 7067, 7080, 7088, 7091, 7084, + 7092, 7094, 7096, 7095, 7097, 7108, 7100, 7098, 7101, 7115, + 7103, 7118, 7125, 7105, 7126, 7127, 7131, 8183, 8183, 8183, + 7122, 7128, 7133, 7135, 7142, 7138, 7141, 8183, 7145, 7143, + 8183, 7146, 7150, 7147, 7154, 7162, 7157, 7159, 8183, 7155, + 7160, 7163, 7164, 7166, 7168, 7169, 7170, 8183, 7172, 7181, + 7183, 7184, 7176, 7186, 7193, 7195, 7197, 7198, 7199, 7201, + 7202, 7203, 7210, 7206, 8183, 8183, 7209, 7205, 8183, 7213, + 7217, 8183, 8183, 7214, 7218, 8183, 7219, 7222, 7223, 7224, + + 7225, 8183, 7228, 7230, 7231, 7234, 8183, 7232, 7236, 7238, + 7235, 7240, 7254, 7243, 7249, 7251, 7264, 7257, 7261, 8183, + 7262, 7272, 7259, 7267, 7268, 7270, 8183, 8183, 7271, 7282, + 8183, 7284, 7285, 7274, 7293, 7289, 7291, 7295, 7297, 8183, + 7296, 7278, 8183, 7300, 7303, 7305, 7306, 7309, 7307, 7310, + 7311, 7315, 8183, 7316, 7313, 7317, 7318, 8183, 7323, 7320, + 7327, 7328, 7330, 8183, 7334, 7331, 7346, 7342, 8183, 7333, + 7352, 7343, 8183, 8183, 8183, 7358, 7360, 7350, 8183, 8183, + 8183, 7348, 7361, 8183, 7365, 7362, 7368, 7370, 8183, 7371, + 8183, 8183, 7373, 7374, 7378, 7382, 7384, 7391, 7377, 8183, + + 7385, 7392, 7395, 7396, 7397, 8183, 7399, 7403, 8183, 7406, + 7410, 7413, 7408, 7418, 7420, 7421, 7405, 7409, 7423, 7427, + 7412, 7415, 8183, 8183, 7431, 7432, 7433, 7434, 7436, 8183, + 7440, 7441, 7109, 7442, 7445, 7446, 7448, 7453, 7460, 7463, + 7450, 7454, 7465, 7464, 7480, 7477, 7457, 7466, 7467, 7478, + 7484, 7468, 7486, 7496, 7491, 7493, 7495, 7498, 7499, 8183, + 8183, 7501, 7502, 7506, 8183, 7508, 7503, 8183, 7509, 8183, + 7511, 7515, 7518, 7520, 7522, 8183, 7524, 7526, 7529, 7531, + 7532, 8183, 7533, 7535, 8183, 8183, 7536, 7537, 7539, 7538, + 7540, 8183, 8183, 7545, 7550, 7548, 7546, 8183, 7547, 7552, + + 7549, 7564, 7554, 7561, 7565, 7570, 7567, 7572, 7576, 8183, + 7573, 7579, 8183, 8183, 8183, 7580, 7581, 7587, 7582, 7591, + 7583, 8183, 7593, 7595, 7597, 7598, 7594, 7600, 7604, 8183, + 7606, 7605, 8183, 8183, 7615, 7602, 8183, 7609, 8183, 8183, + 7607, 7616, 8183, 8183, 8183, 8183, 8183, 8183, 8183, 8183, + 8183, 7621, 7622, 8183, 7623, 7628, 7627, 7624, 7630, 7634, + 8183, 7631, 7639, 7641, 7646, 8183, 7648, 8183, 7635, 7642, + 7653, 7654, 7656, 7660, 8183, 7659, 8183, 7667, 7662, 7665, + 7663, 7664, 7669, 7670, 7677, 7672, 7678, 7679, 7680, 7682, + 7683, 7681, 7689, 7686, 7687, 7698, 7700, 7702, 7688, 7704, + + 7709, 7711, 7706, 7712, 7713, 7714, 7715, 8183, 8183, 8183, + 8183, 7716, 7718, 7724, 7727, 8183, 7725, 7733, 7735, 7741, + 7744, 7746, 7729, 7737, 7747, 7749, 7751, 7739, 7752, 7759, + 7755, 7758, 7760, 7762, 7763, 7772, 7774, 7776, 8183, 7778, + 7779, 7780, 8183, 7782, 7766, 7787, 7791, 7788, 7792, 7794, + 8183, 7795, 7796, 8183, 7797, 7798, 8183, 8183, 7800, 7801, + 7804, 7805, 7814, 7815, 7806, 7813, 7817, 7818, 7828, 8183, + 7830, 8183, 8183, 8183, 8183, 7819, 7822, 8183, 7825, 8183, + 8183, 7831, 7833, 8183, 7832, 7839, 7835, 7841, 8183, 7842, + 7843, 7844, 7847, 7854, 7849, 7850, 7856, 7858, 8183, 8183, + + 7859, 7864, 7865, 7866, 7869, 7870, 8183, 7872, 7874, 7871, + 7884, 7890, 7877, 7888, 7892, 7875, 7901, 8183, 7879, 7896, + 7898, 7904, 7900, 7907, 7908, 8183, 7909, 7910, 7911, 7912, + 7914, 7921, 7917, 7919, 7923, 7925, 7928, 8183, 7934, 8183, + 7937, 7939, 7940, 7941, 7943, 7944, 7945, 7947, 7950, 8183, + 8183, 8183, 7951, 7953, 8183, 7930, 7959, 7954, 7965, 7967, + 7969, 7970, 7961, 7972, 7976, 7978, 7979, 7985, 7982, 7986, + 7987, 7990, 7988, 8183, 8183, 7992, 7994, 8183, 7996, 7997, + 7998, 7999, 8003, 8183, 8009, 8000, 8005, 8010, 8015, 8016, + 8183, 8021, 8026, 8022, 8183, 8027, 8183, 8183, 8028, 8012, + + 8030, 8035, 8037, 8183, 8183, 8183, 8063, 8070, 8077, 8084, + 8091, 8098, 8105, 88, 8112, 8119, 8126, 8133, 8140, 8147, + 8154, 8161, 8168, 8175 } ; -static yyconst flex_int16_t yy_def[4136] = +static yyconst flex_int16_t yy_def[4225] = { 0, - 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 + 4206, 1, 4207, 4207, 4208, 4208, 4209, 4209, 4210, 4210, + 4211, 4211, 4212, 4212, 4213, 4213, 4206, 4214, 4206, 4206, + 4206, 4206, 4215, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4216, 4206, 4206, + 4206, 4216, 4217, 4206, 4206, 4206, 4217, 4218, 4206, 4206, + 4206, 4206, 4218, 4219, 4206, 4206, 4206, 4219, 4220, 4206, + 4221, 4206, 4220, 4220, 4222, 4206, 4206, 4206, 4206, 4222, + 4223, 4206, 4206, 4206, 4223, 4214, 4214, 4206, 4224, 4215, + 4224, 4215, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4216, 4216, 4217, 4217, 4218, 4218, + 4206, 4219, 4219, 4220, 4220, 4221, 4221, 4220, 4222, 4222, + 4206, 4223, 4223, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4220, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4220, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4220, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4220, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4206, 4206, 4214, 4214, 4206, 4206, 4214, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4220, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4206, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4206, 4206, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4220, 4220, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, + + 4214, 4214, 4220, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4206, 4214, + 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4206, 4214, 4214, + + 4214, 4214, 4214, 4214, 4206, 4214, 4206, 4214, 4214, 4214, + 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4220, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4206, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4206, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4206, 4214, 4206, 4214, 4214, 4214, 4220, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4206, 4214, + 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, + 4206, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4220, 4214, 4206, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4206, 4214, 4214, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4206, 4214, + 4206, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, + 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + 4214, 4206, 4206, 4214, 4206, 4214, 4214, 4214, 4206, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, + 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4206, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4206, 4214, + 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4214, 4220, 4214, 4214, 4214, 4214, 4206, 4214, 4214, + 4206, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4206, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4220, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4206, 4214, 4206, 4214, 4214, 4214, 4214, 4214, + 4206, 4214, 4214, 4214, 4214, 4214, 4206, 4206, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4206, 4214, 4206, + 4214, 4206, 4214, 4214, 4206, 4206, 4214, 4214, 4214, 4214, + 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, + 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4220, 4214, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4206, 4206, 4206, 4214, 4214, 4206, 4214, + + 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, + 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, + 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4206, 4206, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, + + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4206, 4214, 4206, 4206, 4206, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4206, 4206, 4214, 4206, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4206, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4220, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + 4214, 4206, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4206, + 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4206, 4206, 4214, 4214, 4214, 4206, + 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4206, + 4214, 4206, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4206, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + 4206, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, + 4206, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4206, 4214, + 4214, 4214, 4214, 4214, 4220, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4206, 4214, 4214, + 4214, 4206, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4206, 4206, 4214, 4206, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4206, 4214, 4206, 4206, 4206, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4206, + 4206, 4206, 4214, 4214, 4214, 4206, 4214, 4214, 4206, 4214, + 4206, 4214, 4206, 4214, 4214, 4214, 4206, 4214, 4206, 4214, + + 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4206, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4206, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4206, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4206, 4214, 4206, 4214, 4206, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4206, 4206, 4214, 4214, 4206, + 4214, 4214, 4214, 4206, 4214, 4206, 4214, 4214, 4206, 4214, + 4214, 4206, 4214, 4214, 4214, 4206, 4206, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4206, + 4214, 4214, 4214, 4206, 4206, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4206, 4206, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, + 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4206, 4206, 4214, 4214, 4206, 4214, + 4214, 4206, 4206, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + + 4214, 4206, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4206, 4214, 4214, + 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4206, 4214, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4206, 4206, 4206, 4214, 4214, 4214, 4206, 4206, + 4206, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4206, 4214, + 4206, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + + 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4206, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4206, 4206, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4206, 4214, 4214, 4214, 4206, 4214, 4214, 4206, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + 4214, 4206, 4214, 4214, 4206, 4206, 4214, 4214, 4214, 4214, + 4214, 4206, 4206, 4214, 4214, 4214, 4214, 4206, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4214, 4206, 4206, 4206, 4214, 4214, 4214, 4214, 4214, + 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4214, 4206, 4206, 4214, 4214, 4206, 4214, 4206, 4206, + 4214, 4214, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, + 4206, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, + 4206, 4214, 4214, 4214, 4214, 4206, 4214, 4206, 4214, 4214, + 4214, 4214, 4214, 4214, 4206, 4214, 4206, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4206, 4206, + 4206, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4206, 4214, 4214, 4206, 4214, 4214, 4206, 4206, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4214, 4206, 4206, 4206, 4206, 4214, 4214, 4206, 4214, 4206, + 4206, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4206, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4206, + + 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, 4214, 4206, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4206, + 4206, 4206, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, 4214, + 4214, 4214, 4214, 4206, 4206, 4214, 4214, 4206, 4214, 4214, + 4214, 4214, 4214, 4206, 4214, 4214, 4214, 4214, 4214, 4214, + 4206, 4214, 4214, 4214, 4206, 4214, 4206, 4206, 4214, 4214, + + 4214, 4214, 4214, 4206, 4206, 0, 4206, 4206, 4206, 4206, + 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, + 4206, 4206, 4206, 4206 } ; -static yyconst flex_int16_t yy_nxt[8064] = +static yyconst flex_int16_t yy_nxt[8224] = { 0, 18, 19, 20, 21, 22, 23, 22, 18, 18, 18, 18, 18, 22, 24, 25, 26, 27, 28, 29, 30, @@ -1885,805 +1915,823 @@ static yyconst flex_int16_t yy_nxt[8064] 87, 471, 458, 87, 87, 467, 465, 478, 463, 490, 464, 87, 466, 87, 470, 87, 474, 87, 472, 480, 476, 473, 475, 479, 87, 87, 87, 481, 87, 87, - 87, 87, 180, 500, 492, 87, 505, 477, 482, 87, - 87, 506, 87, 483, 501, 87, 491, 502, 484, 516, - 87, 485, 503, 504, 509, 87, 486, 487, 488, 489, - 87, 507, 87, 493, 87, 494, 87, 495, 87, 508, - 522, 87, 87, 87, 87, 518, 87, 496, 497, 498, - 596, 499, 87, 517, 87, 510, 512, 513, 511, 519, - 514, 515, 87, 520, 87, 521, 87, 523, 525, 87, - - 87, 524, 87, 87, 87, 87, 530, 87, 87, 537, - 536, 526, 87, 87, 531, 87, 532, 87, 529, 527, - 87, 87, 528, 87, 619, 533, 538, 535, 539, 549, - 87, 543, 534, 541, 540, 542, 544, 87, 87, 550, - 545, 551, 87, 552, 87, 87, 87, 87, 87, 87, - 553, 567, 87, 546, 175, 175, 547, 87, 548, 87, - 554, 87, 555, 87, 569, 87, 566, 570, 556, 568, - 87, 571, 557, 572, 584, 574, 590, 558, 583, 87, - 559, 87, 560, 173, 561, 585, 587, 87, 87, 573, - 586, 87, 87, 87, 588, 87, 593, 562, 591, 87, - - 563, 589, 564, 595, 565, 87, 87, 575, 576, 87, - 592, 87, 594, 87, 87, 87, 602, 577, 578, 579, - 580, 581, 600, 87, 582, 597, 598, 599, 87, 606, - 87, 87, 601, 87, 603, 604, 607, 87, 608, 87, - 610, 87, 611, 605, 87, 609, 87, 87, 87, 617, - 87, 613, 87, 87, 87, 87, 87, 612, 620, 171, - 87, 615, 614, 87, 621, 622, 616, 87, 87, 87, - 627, 628, 623, 629, 624, 618, 625, 87, 87, 626, - 630, 631, 87, 87, 87, 636, 633, 634, 87, 87, - 87, 87, 87, 87, 87, 652, 637, 655, 632, 642, - - 643, 87, 635, 638, 87, 639, 641, 87, 640, 654, - 170, 644, 87, 645, 87, 658, 653, 657, 87, 646, - 87, 656, 87, 87, 659, 662, 660, 647, 648, 87, - 87, 649, 650, 661, 87, 651, 87, 664, 666, 87, - 87, 87, 87, 87, 670, 671, 668, 665, 87, 663, - 87, 87, 87, 672, 673, 669, 87, 87, 87, 667, - 87, 678, 676, 677, 87, 87, 87, 674, 87, 679, - 87, 87, 87, 684, 87, 87, 680, 675, 87, 687, - 683, 87, 689, 685, 682, 681, 688, 690, 87, 691, - 87, 87, 87, 686, 696, 692, 87, 694, 87, 697, - - 87, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 699, 703, 693, 701, 695, 87, 87, 710, 87, 712, - 705, 87, 698, 87, 700, 87, 702, 704, 168, 709, - 87, 87, 711, 706, 708, 707, 716, 713, 87, 715, - 714, 87, 87, 717, 87, 718, 87, 721, 87, 719, - 87, 725, 720, 87, 87, 87, 728, 87, 727, 724, - 722, 87, 87, 723, 87, 87, 731, 87, 730, 734, - 87, 87, 87, 726, 87, 87, 736, 738, 87, 87, - 729, 87, 87, 87, 166, 87, 732, 735, 733, 737, - 87, 739, 741, 87, 753, 87, 773, 740, 87, 742, - - 752, 750, 754, 751, 743, 87, 744, 87, 87, 756, - 755, 757, 745, 87, 746, 87, 87, 747, 748, 87, - 761, 758, 87, 760, 749, 759, 87, 766, 765, 763, - 87, 87, 764, 87, 770, 87, 87, 768, 767, 87, - 762, 87, 769, 87, 775, 87, 87, 779, 87, 87, - 87, 87, 87, 771, 776, 772, 778, 777, 87, 783, - 87, 774, 87, 782, 787, 87, 87, 780, 786, 87, - 784, 781, 175, 789, 788, 785, 790, 791, 792, 87, - 87, 87, 796, 87, 87, 87, 87, 87, 87, 801, - 799, 87, 87, 87, 793, 795, 804, 87, 87, 794, - - 797, 803, 798, 805, 800, 807, 808, 87, 87, 87, - 806, 87, 87, 87, 87, 87, 802, 810, 87, 809, - 813, 87, 811, 87, 87, 814, 815, 87, 812, 87, - 836, 87, 821, 817, 824, 87, 816, 822, 87, 87, - 818, 825, 87, 819, 823, 820, 826, 827, 87, 828, - 87, 829, 87, 87, 830, 87, 831, 833, 87, 87, - 87, 832, 87, 87, 837, 87, 87, 87, 87, 840, - 835, 87, 841, 839, 87, 845, 834, 87, 844, 87, - 87, 87, 838, 847, 87, 87, 87, 851, 87, 849, - 843, 842, 87, 87, 87, 87, 87, 846, 848, 850, - - 854, 858, 87, 852, 87, 87, 87, 87, 87, 859, - 856, 87, 855, 853, 87, 87, 857, 861, 898, 860, - 865, 87, 862, 87, 866, 863, 864, 87, 87, 867, - 87, 868, 869, 870, 87, 871, 874, 873, 87, 87, - 87, 87, 87, 876, 87, 872, 880, 875, 877, 87, - 87, 87, 881, 87, 87, 882, 87, 87, 879, 87, - 87, 885, 887, 889, 87, 87, 87, 883, 87, 886, - 878, 884, 87, 893, 890, 892, 87, 87, 87, 888, - 87, 899, 87, 901, 87, 891, 897, 87, 900, 87, - 895, 87, 905, 894, 896, 902, 903, 87, 87, 87, - - 904, 87, 906, 87, 87, 912, 87, 87, 910, 907, - 914, 87, 913, 908, 87, 909, 87, 915, 87, 87, - 919, 87, 87, 911, 917, 920, 87, 87, 87, 87, - 87, 916, 931, 183, 918, 921, 922, 923, 87, 933, - 924, 87, 87, 87, 925, 87, 926, 934, 932, 87, - 936, 87, 937, 927, 87, 87, 941, 939, 938, 928, - 929, 930, 87, 935, 87, 945, 87, 942, 87, 943, - 946, 87, 940, 87, 947, 87, 87, 949, 951, 944, - 87, 87, 87, 87, 87, 87, 958, 950, 87, 87, - 87, 948, 87, 959, 87, 87, 87, 960, 87, 953, - - 954, 952, 955, 957, 956, 961, 87, 87, 968, 962, - 965, 87, 87, 963, 87, 964, 87, 87, 969, 966, - 87, 967, 87, 87, 971, 970, 975, 87, 87, 87, - 87, 87, 87, 87, 985, 972, 181, 983, 973, 974, - 87, 976, 87, 977, 87, 87, 978, 979, 980, 981, - 982, 87, 87, 87, 984, 986, 987, 991, 87, 990, - 87, 87, 87, 988, 989, 87, 87, 87, 995, 87, - 996, 87, 87, 997, 992, 994, 999, 1000, 87, 993, - 87, 87, 87, 87, 87, 1002, 87, 1001, 180, 1003, - 1008, 998, 1005, 1006, 1007, 1004, 87, 175, 87, 87, - - 1012, 1010, 1009, 1011, 87, 87, 87, 87, 87, 1015, - 1018, 87, 1021, 1013, 87, 1019, 87, 1022, 87, 87, - 1014, 1016, 87, 1020, 1023, 1024, 1026, 87, 87, 1017, - 87, 87, 87, 87, 1029, 87, 1033, 87, 1034, 87, - 87, 1025, 87, 1030, 87, 1035, 1027, 1037, 1028, 87, - 87, 87, 87, 1032, 1036, 87, 1049, 87, 1031, 87, - 87, 87, 87, 87, 87, 1058, 1051, 1038, 1052, 1050, - 1048, 1040, 1055, 87, 87, 1039, 87, 1056, 1041, 1054, - 87, 1042, 1053, 87, 1057, 1043, 87, 1059, 1044, 87, - 87, 1064, 1061, 87, 1060, 1045, 1046, 87, 1047, 87, - - 87, 87, 87, 1062, 87, 1074, 87, 87, 1077, 87, - 1063, 87, 1065, 1066, 1075, 1067, 175, 87, 1068, 1073, - 1076, 1079, 87, 1069, 1084, 1078, 1082, 1081, 87, 1070, - 1071, 1085, 1072, 1083, 1087, 87, 87, 1080, 1086, 1088, - 87, 87, 1090, 1089, 87, 87, 87, 1093, 87, 87, - 1092, 87, 1095, 1094, 1097, 87, 1096, 87, 87, 1091, - 1098, 87, 87, 87, 87, 87, 1101, 87, 87, 1099, - 87, 1106, 87, 1105, 87, 87, 1110, 87, 87, 87, - 1100, 1102, 87, 1107, 1103, 1114, 1104, 1115, 1109, 87, - 1112, 87, 1108, 1116, 87, 1111, 87, 1117, 1121, 87, - - 1120, 1113, 1118, 87, 1119, 87, 87, 1122, 87, 1125, - 87, 87, 1127, 1128, 87, 87, 1126, 87, 87, 87, - 1129, 1131, 87, 87, 1123, 1130, 1132, 87, 1124, 87, - 87, 1134, 87, 87, 87, 1136, 1137, 1133, 87, 87, - 1138, 1142, 87, 87, 87, 1145, 87, 1135, 87, 1146, - 87, 1144, 1139, 1143, 1140, 87, 87, 87, 1141, 87, - 87, 87, 87, 87, 87, 1149, 1147, 87, 87, 1148, - 1152, 87, 1156, 1157, 87, 1150, 87, 1153, 1155, 1159, - 1158, 87, 87, 87, 1154, 1151, 1160, 1165, 1161, 1162, - 87, 1163, 1166, 87, 87, 1168, 1164, 87, 87, 87, - - 87, 87, 87, 87, 1167, 1174, 87, 87, 1171, 1176, - 1177, 87, 1169, 1175, 87, 87, 87, 1170, 87, 1173, - 1179, 1181, 87, 1182, 1172, 87, 87, 1178, 87, 87, - 87, 87, 87, 1188, 1191, 1180, 87, 1186, 1183, 87, - 87, 1192, 87, 87, 1184, 1185, 87, 87, 1189, 1187, - 1190, 1193, 1194, 1197, 1198, 87, 87, 1196, 87, 1201, - 87, 1195, 87, 1200, 87, 87, 87, 87, 87, 1199, - 87, 87, 87, 1204, 1206, 1202, 87, 1212, 1213, 87, - 1215, 87, 1203, 87, 87, 1205, 87, 1207, 1218, 1209, - 1208, 1210, 1211, 1214, 87, 1216, 1217, 1219, 87, 87, - - 87, 87, 1220, 87, 87, 1227, 1224, 87, 1226, 1228, - 87, 87, 1222, 1229, 87, 87, 87, 1232, 1221, 87, - 1223, 1234, 87, 87, 87, 1225, 87, 87, 87, 1231, - 87, 1237, 1230, 1238, 87, 87, 1245, 87, 1241, 1233, - 1236, 1244, 1235, 1242, 175, 87, 1239, 87, 1240, 1243, - 1246, 87, 87, 87, 87, 87, 1249, 87, 1253, 87, - 87, 87, 1248, 87, 1265, 1247, 1264, 87, 1252, 1254, - 1255, 1250, 87, 87, 1268, 87, 1266, 1251, 87, 1256, - 87, 1257, 87, 87, 87, 1258, 87, 1259, 1267, 1337, - 87, 1260, 1269, 1261, 1270, 1271, 1274, 1275, 1262, 1273, - - 1272, 87, 87, 1263, 1278, 87, 1276, 87, 87, 1279, - 87, 87, 1282, 87, 1280, 87, 1277, 87, 1285, 87, - 1289, 1281, 1286, 87, 1283, 1288, 1284, 1291, 87, 87, - 87, 87, 1287, 1290, 87, 1298, 1295, 87, 87, 1294, - 1296, 87, 1297, 1293, 1292, 1299, 1300, 87, 1301, 1302, - 87, 87, 87, 87, 87, 87, 87, 87, 1317, 87, - 1303, 1314, 87, 87, 87, 87, 1313, 87, 1318, 1304, - 1305, 87, 1306, 1315, 1316, 1319, 87, 1307, 1320, 1308, - 87, 1321, 87, 87, 87, 1309, 1326, 87, 87, 1327, - 1310, 1311, 87, 87, 1322, 1323, 87, 1312, 87, 1325, - - 1328, 1324, 1333, 87, 87, 1329, 87, 1336, 1334, 1330, - 87, 87, 87, 87, 1331, 1341, 1332, 1339, 87, 87, - 87, 87, 87, 1342, 1340, 87, 1335, 1347, 87, 1338, - 87, 1344, 87, 87, 1345, 87, 1346, 87, 1343, 1349, - 1351, 87, 87, 1354, 87, 87, 87, 87, 87, 1348, - 87, 1350, 87, 87, 1357, 1353, 1358, 1352, 1356, 1359, - 1361, 87, 87, 1365, 1355, 1360, 87, 87, 1362, 87, - 1364, 1368, 87, 87, 1367, 1363, 87, 87, 87, 87, - 87, 87, 173, 87, 1373, 1374, 1375, 1370, 1376, 87, - 87, 1369, 1366, 1372, 1371, 87, 1378, 1379, 1377, 1380, - - 87, 87, 87, 87, 87, 87, 1384, 1385, 87, 1381, - 87, 1387, 1386, 87, 1388, 1383, 1382, 87, 87, 1389, - 1390, 87, 1391, 87, 87, 87, 1393, 87, 87, 87, - 87, 1398, 87, 87, 87, 87, 1403, 87, 1392, 1408, - 1395, 1396, 87, 1394, 1397, 1399, 1401, 1402, 1400, 1405, - 1406, 87, 87, 1409, 1404, 87, 1407, 87, 1411, 87, - 1410, 87, 87, 87, 1412, 87, 1413, 87, 87, 87, - 1416, 87, 1415, 1417, 87, 1419, 87, 1423, 1414, 1418, - 1421, 1424, 87, 87, 87, 87, 87, 1420, 87, 1427, - 87, 1428, 87, 1425, 87, 87, 87, 1422, 1432, 1434, - - 171, 1435, 1436, 1426, 87, 87, 1429, 87, 87, 1433, - 87, 1430, 87, 1439, 1431, 1437, 87, 1438, 1441, 87, - 87, 1440, 1443, 87, 87, 1442, 1445, 87, 87, 1447, - 87, 87, 87, 1446, 87, 87, 1448, 87, 87, 1450, - 1449, 1453, 87, 1444, 87, 1454, 87, 87, 87, 87, - 170, 1456, 1460, 1451, 87, 1455, 1452, 1461, 87, 87, - 1458, 1464, 87, 87, 1463, 1457, 87, 87, 1459, 1462, - 87, 87, 1469, 87, 87, 87, 87, 87, 87, 87, - 175, 1466, 1467, 1471, 87, 1465, 1476, 87, 1475, 1468, - 87, 1470, 1477, 87, 1472, 1478, 87, 1474, 1479, 87, - - 1480, 87, 1473, 87, 87, 87, 87, 87, 1484, 87, - 1481, 1487, 87, 1483, 1482, 1485, 1489, 1490, 87, 1486, - 87, 1497, 87, 87, 1492, 1488, 1491, 87, 87, 87, - 1495, 87, 1494, 87, 1496, 87, 1493, 87, 1499, 87, - 87, 87, 1502, 87, 87, 1498, 87, 1503, 1506, 87, - 1500, 87, 87, 87, 87, 1509, 1501, 1508, 1504, 87, - 1505, 1511, 1510, 87, 87, 1507, 1523, 87, 1515, 1512, - 1513, 87, 1514, 87, 1520, 1519, 87, 1516, 87, 1517, - 87, 1521, 1518, 1522, 87, 87, 87, 87, 1526, 87, - 87, 1524, 87, 1533, 1525, 1530, 1529, 87, 87, 87, - - 87, 87, 87, 1534, 87, 1527, 87, 1528, 87, 1532, - 1543, 1531, 1536, 1539, 1535, 1538, 87, 87, 87, 87, - 87, 1537, 1540, 1542, 1541, 87, 87, 87, 1544, 87, - 1548, 87, 87, 87, 87, 1545, 87, 87, 1551, 1549, - 1546, 87, 1556, 1560, 1550, 1547, 1552, 87, 87, 87, - 87, 1553, 87, 87, 1554, 1555, 1557, 87, 1558, 87, - 87, 1563, 87, 87, 87, 1566, 87, 1570, 1561, 1559, - 1562, 1572, 1564, 87, 87, 87, 87, 87, 1565, 1567, - 87, 1569, 87, 1571, 1576, 87, 87, 1568, 1575, 1573, - 1574, 1577, 87, 1580, 1579, 87, 87, 1578, 1581, 87, - - 1583, 87, 1585, 87, 1582, 1593, 87, 87, 1584, 87, - 1586, 87, 1597, 1690, 1587, 1596, 1595, 1588, 1589, 1594, - 87, 87, 1590, 87, 87, 1598, 87, 1599, 1591, 1601, - 87, 1602, 1592, 1600, 87, 87, 87, 1604, 87, 1603, - 87, 1606, 87, 87, 87, 1608, 1613, 1609, 1614, 1607, - 87, 1605, 87, 1615, 87, 87, 1612, 87, 1610, 87, - 87, 1611, 87, 1621, 1616, 1618, 87, 87, 1623, 87, - 87, 1625, 1622, 1619, 87, 1624, 87, 1617, 87, 87, - 1620, 87, 87, 1634, 1632, 1635, 1636, 1627, 87, 1626, - 87, 87, 1628, 87, 1629, 1633, 1630, 1638, 1631, 87, - - 87, 1637, 87, 1643, 87, 87, 1639, 1644, 87, 1645, - 87, 1642, 87, 87, 1646, 87, 87, 1651, 1641, 1640, - 87, 87, 1649, 1647, 87, 1650, 1648, 87, 87, 1653, - 87, 87, 1659, 87, 1660, 1654, 1655, 87, 87, 87, - 87, 87, 1652, 87, 87, 1658, 1666, 1656, 1662, 1657, - 1667, 1661, 87, 87, 87, 1663, 87, 1664, 1665, 1671, - 87, 1670, 87, 1673, 87, 87, 87, 87, 1675, 87, - 1674, 1668, 1676, 87, 87, 1680, 87, 1672, 1677, 1669, - 87, 1682, 87, 1679, 87, 1683, 1678, 87, 87, 87, - 87, 168, 1684, 1688, 87, 87, 87, 87, 1693, 1691, - - 1681, 87, 87, 87, 87, 87, 1694, 1696, 87, 1685, - 1686, 1687, 1695, 87, 87, 1689, 1698, 1692, 87, 87, - 1697, 87, 87, 1699, 1701, 166, 1703, 1700, 87, 87, - 1704, 87, 1702, 1705, 1706, 87, 87, 1708, 87, 87, - 1707, 87, 87, 1709, 1714, 1711, 1715, 1710, 1712, 87, - 87, 87, 87, 1718, 1716, 1713, 1717, 87, 87, 87, - 87, 1722, 87, 87, 87, 87, 1719, 87, 87, 87, - 1725, 1721, 175, 87, 1731, 1732, 87, 1720, 1727, 87, - 87, 87, 1733, 1723, 1724, 1726, 1735, 1728, 87, 1729, - 1734, 87, 87, 87, 1741, 87, 1730, 87, 1740, 87, - - 87, 87, 1736, 87, 1746, 1738, 87, 87, 1737, 1743, - 87, 1739, 87, 1744, 87, 1742, 87, 1750, 87, 1745, - 1752, 87, 87, 1754, 87, 1758, 1747, 87, 1749, 87, - 1759, 87, 1748, 87, 1751, 87, 87, 1753, 1756, 87, - 1757, 1755, 87, 87, 1762, 87, 87, 1760, 87, 87, - 1763, 1761, 1774, 1764, 1768, 1770, 87, 1769, 1765, 87, - 1766, 1771, 1772, 1767, 1773, 87, 1777, 1776, 87, 1775, - 87, 1778, 87, 87, 87, 87, 87, 87, 87, 87, - 1782, 1783, 1784, 87, 1787, 87, 87, 1779, 87, 87, - 87, 1792, 1781, 87, 87, 87, 1785, 1793, 1796, 1780, - - 1789, 87, 87, 1786, 87, 1788, 1790, 1791, 87, 87, - 87, 87, 1794, 1797, 1795, 87, 87, 87, 1798, 87, - 87, 1804, 87, 1800, 1805, 1801, 1802, 1799, 87, 87, - 87, 87, 1812, 1806, 1803, 1809, 1808, 1807, 1811, 87, - 87, 1810, 87, 87, 1816, 1817, 1818, 87, 87, 1814, - 87, 87, 87, 87, 1813, 87, 1820, 1821, 87, 1822, - 87, 1819, 1815, 1826, 1823, 1825, 1827, 1828, 87, 87, - 87, 1824, 87, 87, 87, 1829, 87, 1830, 1833, 87, - 87, 87, 1837, 87, 1834, 87, 1836, 87, 87, 1841, - 1835, 87, 87, 87, 1840, 87, 1831, 1838, 1832, 1844, - - 1839, 1843, 87, 1848, 87, 87, 1846, 1845, 1849, 87, - 1850, 1842, 87, 87, 1847, 1851, 87, 1852, 87, 1854, - 87, 87, 87, 87, 1853, 87, 87, 1858, 1863, 87, - 1857, 1855, 87, 87, 87, 1865, 87, 1864, 87, 1856, - 87, 87, 1859, 1870, 1860, 87, 1861, 1862, 87, 87, - 87, 1866, 1873, 1868, 1872, 87, 1867, 87, 87, 87, - 87, 87, 87, 87, 1871, 87, 1869, 87, 1875, 1874, - 87, 1883, 87, 87, 1876, 1884, 1877, 1880, 87, 1878, - 1879, 87, 1882, 1881, 1885, 1888, 87, 1889, 87, 87, - 1887, 87, 1886, 87, 1890, 1891, 1893, 87, 87, 87, - - 87, 1896, 87, 1899, 87, 1897, 1892, 1894, 87, 1900, - 1895, 87, 87, 87, 1902, 87, 87, 87, 1898, 87, - 1904, 1903, 1908, 87, 1909, 1910, 1901, 87, 1905, 1913, - 87, 87, 87, 1907, 87, 87, 1906, 1914, 1915, 87, - 87, 87, 1911, 1912, 1916, 87, 87, 1921, 1922, 87, - 1919, 87, 1924, 87, 87, 87, 87, 1927, 87, 1917, - 1926, 1928, 87, 1918, 1930, 87, 1920, 87, 87, 1923, - 87, 1931, 1932, 87, 87, 1925, 87, 87, 87, 87, - 1936, 87, 1929, 87, 87, 1941, 1933, 87, 1939, 87, - 1934, 87, 1935, 87, 87, 87, 1945, 87, 1947, 1937, - - 87, 1938, 1942, 1940, 87, 87, 1948, 87, 1946, 1949, - 1943, 87, 1944, 1950, 87, 1954, 87, 1953, 87, 87, - 87, 87, 1951, 1957, 1959, 87, 87, 87, 87, 1962, - 1955, 1960, 87, 87, 87, 1958, 1952, 1956, 1966, 87, - 87, 1961, 1969, 87, 1965, 1968, 87, 1970, 1963, 1972, - 87, 1964, 1971, 87, 87, 175, 87, 87, 1967, 1974, - 87, 87, 87, 1973, 87, 87, 1983, 1984, 87, 87, - 87, 1975, 87, 87, 1976, 1977, 1978, 1979, 1980, 1982, - 87, 87, 1991, 1988, 87, 1981, 1986, 87, 1985, 1987, - 87, 1989, 1990, 87, 87, 1992, 1994, 87, 87, 1996, - - 1998, 87, 1995, 1999, 1993, 87, 87, 1997, 2001, 87, - 87, 87, 87, 87, 87, 2000, 87, 2004, 87, 2005, - 87, 2006, 87, 2007, 87, 2009, 87, 2010, 87, 2002, - 2003, 87, 87, 87, 2011, 2014, 87, 2015, 2008, 87, - 2012, 87, 2023, 2013, 87, 2017, 87, 2019, 87, 2016, - 2020, 2024, 87, 2022, 87, 2025, 87, 87, 4117, 2018, - 87, 2028, 2021, 2027, 87, 2031, 87, 2030, 2033, 2034, - 2038, 2026, 87, 87, 87, 87, 87, 2035, 87, 2036, - 87, 2037, 2029, 87, 2032, 87, 2040, 87, 2039, 87, - 87, 2045, 2046, 2044, 2047, 87, 87, 87, 87, 2049, - - 87, 2048, 87, 2041, 87, 87, 2042, 2051, 87, 2043, - 2052, 87, 87, 2053, 87, 87, 87, 87, 2050, 87, - 87, 87, 2054, 87, 87, 87, 87, 87, 2068, 2056, - 2065, 87, 2055, 2057, 2060, 2058, 87, 2059, 2061, 2062, - 87, 2063, 2066, 2069, 2064, 87, 2067, 2072, 2070, 87, - 87, 87, 87, 87, 87, 2077, 87, 2079, 2071, 2081, - 87, 87, 87, 87, 87, 2085, 2074, 87, 2076, 2073, - 2080, 2075, 2083, 2078, 87, 2084, 87, 87, 87, 87, - 87, 87, 2082, 2091, 87, 87, 87, 87, 2090, 2086, - 2087, 87, 2094, 87, 2092, 2095, 2089, 2097, 2096, 2093, - - 87, 2088, 2098, 2102, 2103, 87, 87, 2099, 87, 2100, - 2104, 87, 87, 87, 87, 2107, 2109, 87, 2101, 87, - 2105, 87, 87, 87, 2106, 87, 2112, 2110, 2108, 87, - 2114, 87, 2115, 87, 87, 87, 2117, 87, 2111, 2113, - 87, 87, 87, 2126, 2116, 87, 2120, 87, 2128, 87, - 2119, 2125, 2118, 87, 2121, 87, 2122, 2127, 87, 2123, - 87, 87, 2134, 87, 2124, 2129, 2130, 2135, 87, 87, - 87, 87, 4117, 2131, 2132, 2136, 87, 2133, 87, 2140, - 87, 2137, 87, 2141, 87, 87, 2144, 87, 2138, 2139, - 2145, 2143, 2142, 87, 2146, 87, 2148, 87, 2150, 2149, - - 2151, 87, 87, 2153, 87, 87, 2152, 2154, 2147, 87, - 2158, 87, 87, 2155, 87, 2159, 87, 87, 87, 87, - 2167, 87, 2163, 87, 2165, 2160, 2156, 2157, 2169, 2161, - 87, 87, 2164, 2168, 2162, 2171, 87, 2166, 87, 87, - 87, 87, 2172, 87, 2176, 2170, 87, 2180, 87, 87, - 87, 87, 87, 87, 87, 2178, 2181, 2175, 2173, 2177, - 2174, 2179, 87, 87, 87, 87, 87, 2186, 2182, 87, - 2183, 2185, 87, 2184, 2187, 2189, 87, 2188, 2193, 87, - 87, 2195, 2190, 2196, 87, 87, 2191, 87, 2197, 87, - 2192, 2199, 87, 2198, 87, 87, 2203, 87, 87, 2205, - - 2194, 87, 87, 87, 2200, 87, 2209, 87, 87, 87, - 87, 2204, 2201, 2211, 2202, 2212, 87, 87, 2207, 87, - 87, 2208, 2214, 2206, 2215, 87, 87, 87, 2210, 2216, - 2218, 87, 87, 175, 87, 2222, 2213, 2220, 2225, 87, - 2221, 2219, 87, 87, 87, 2223, 2229, 87, 2217, 2224, - 87, 87, 87, 87, 87, 2227, 2230, 87, 87, 2232, - 87, 2226, 87, 2228, 2231, 2233, 2235, 2234, 2236, 87, - 2240, 87, 87, 87, 2244, 87, 87, 87, 2237, 2243, - 2245, 2238, 87, 2241, 2247, 87, 87, 2249, 87, 2239, - 2242, 2248, 87, 87, 87, 2254, 87, 87, 2253, 87, - - 87, 2251, 2246, 2250, 87, 87, 87, 2256, 87, 2255, - 2252, 2257, 87, 87, 87, 87, 87, 87, 2262, 2258, - 2263, 87, 2259, 2264, 2260, 87, 2267, 87, 2265, 87, - 2261, 87, 2266, 87, 2268, 87, 2269, 2277, 2274, 87, - 2272, 2276, 87, 87, 87, 2271, 2275, 2273, 87, 2270, - 87, 87, 87, 87, 87, 2284, 87, 2287, 2288, 87, - 2278, 2289, 87, 2280, 2279, 87, 87, 2282, 2285, 2281, - 2286, 87, 2283, 2291, 87, 87, 2292, 87, 2296, 87, - 87, 87, 2298, 87, 2297, 2290, 2299, 2293, 87, 2300, - 2302, 87, 2294, 87, 87, 87, 87, 87, 2295, 2301, - - 87, 87, 2304, 87, 2307, 2305, 2308, 87, 2310, 2311, - 87, 87, 87, 87, 2303, 87, 87, 2309, 2314, 2306, - 2315, 87, 2316, 87, 2318, 87, 2312, 87, 2317, 87, - 87, 87, 87, 2313, 2326, 87, 2323, 2319, 2320, 2321, - 87, 87, 2329, 87, 2322, 2324, 2330, 87, 2331, 2325, - 87, 2327, 2328, 2332, 87, 87, 87, 2333, 2335, 2338, - 87, 2336, 2334, 87, 87, 87, 87, 87, 87, 2339, - 2337, 2344, 87, 87, 2346, 87, 87, 87, 2341, 87, - 2349, 2350, 87, 2340, 87, 2342, 2351, 87, 2343, 2353, - 87, 87, 2356, 87, 2345, 2347, 87, 2352, 2348, 87, - - 2355, 2359, 87, 87, 87, 2357, 87, 87, 87, 2354, - 2364, 87, 87, 87, 87, 87, 87, 87, 2363, 2367, - 2358, 87, 2361, 2360, 2362, 2368, 2375, 2365, 2366, 87, - 2370, 2371, 87, 2373, 87, 4117, 2374, 2376, 87, 87, - 2369, 2372, 87, 87, 2379, 2378, 87, 2382, 2380, 87, - 87, 2383, 87, 87, 2377, 87, 87, 87, 2381, 87, - 2384, 87, 87, 87, 2386, 2385, 2389, 87, 87, 87, - 2391, 87, 2394, 2390, 87, 87, 2397, 2387, 2388, 2395, - 2392, 2400, 87, 87, 2399, 87, 2398, 87, 87, 2396, - 87, 87, 87, 87, 2393, 2403, 2408, 87, 2407, 87, - - 87, 87, 87, 2402, 87, 2401, 87, 2414, 2413, 87, - 2405, 2404, 87, 87, 2406, 2415, 2411, 2417, 87, 2410, - 87, 2412, 2416, 2409, 87, 87, 2422, 87, 2419, 2418, - 87, 87, 87, 2423, 87, 87, 2420, 2426, 87, 2430, - 87, 2421, 87, 87, 2424, 87, 87, 87, 2433, 4117, - 2425, 2435, 87, 2434, 2427, 2428, 87, 2436, 2429, 87, - 2431, 2432, 87, 2437, 87, 87, 87, 2441, 2443, 87, - 2442, 2438, 2444, 87, 87, 2439, 2445, 2447, 2448, 2450, - 2440, 2446, 87, 87, 87, 87, 87, 2452, 87, 87, - 87, 87, 2449, 87, 2454, 87, 2456, 2451, 2453, 2458, - - 2455, 2460, 87, 87, 87, 87, 87, 87, 2462, 2463, - 87, 175, 87, 2459, 2457, 87, 2466, 2461, 87, 4117, - 87, 2471, 87, 2464, 2467, 2470, 2465, 2468, 87, 87, - 2473, 2472, 2474, 87, 87, 2475, 2477, 2469, 2476, 87, - 87, 87, 87, 2480, 87, 87, 87, 87, 87, 87, - 2481, 2482, 87, 2483, 2484, 2478, 87, 2485, 2486, 2488, - 87, 2479, 87, 2487, 87, 87, 2489, 87, 2493, 2490, - 87, 87, 2491, 87, 2497, 87, 87, 87, 2496, 87, - 2492, 87, 2494, 2495, 2499, 2498, 2500, 87, 2502, 87, - 2501, 87, 87, 87, 87, 2507, 2510, 2503, 2508, 87, - - 2504, 87, 87, 87, 2509, 87, 87, 87, 87, 87, - 2505, 87, 2506, 87, 2512, 87, 2515, 87, 2518, 87, - 2519, 2511, 2514, 87, 2513, 2517, 2522, 2516, 87, 2521, - 87, 2523, 87, 2520, 87, 2525, 2527, 87, 87, 87, - 87, 2528, 87, 2534, 2524, 2526, 87, 87, 87, 87, - 2529, 87, 2536, 87, 4117, 2530, 2531, 2532, 87, 87, - 2533, 2537, 2538, 87, 2535, 2541, 87, 87, 87, 2539, - 87, 2540, 2543, 87, 2546, 2542, 87, 2544, 2547, 87, - 87, 2545, 87, 87, 87, 87, 2552, 2549, 87, 2553, - 87, 87, 2550, 2548, 87, 87, 87, 2554, 87, 87, - - 87, 87, 2551, 2556, 2555, 2558, 2557, 2559, 2561, 2563, - 87, 87, 87, 2562, 2564, 87, 87, 4117, 87, 2574, - 2566, 2567, 2560, 2565, 2568, 2573, 87, 87, 2572, 87, - 2570, 2582, 2575, 87, 2571, 87, 2576, 2569, 87, 2578, - 2577, 2579, 87, 87, 87, 87, 87, 2580, 2581, 87, - 2584, 87, 87, 2585, 87, 87, 87, 2590, 2586, 87, - 87, 2588, 2583, 87, 2594, 87, 2589, 2596, 87, 2587, - 87, 2598, 87, 87, 2592, 2591, 87, 87, 87, 2601, - 2593, 2600, 2597, 2595, 87, 87, 87, 87, 2607, 2602, - 2603, 87, 87, 87, 87, 2611, 2604, 2608, 87, 2599, - - 2612, 87, 87, 2610, 2605, 87, 2609, 2606, 87, 87, - 2613, 2617, 87, 87, 2618, 87, 87, 2614, 87, 2615, - 2616, 2622, 87, 2623, 2620, 2625, 2619, 87, 87, 2626, - 2624, 87, 2628, 2629, 87, 87, 2621, 87, 87, 87, - 2627, 87, 2630, 2632, 87, 87, 2634, 87, 2635, 2633, - 2631, 87, 87, 87, 87, 87, 87, 2637, 2639, 2638, - 2636, 87, 2640, 2642, 2644, 2641, 87, 87, 2646, 2645, - 87, 87, 87, 87, 87, 2647, 2643, 2651, 87, 2648, - 87, 87, 87, 2652, 2649, 2650, 87, 2653, 2654, 87, - 2656, 2657, 87, 87, 87, 87, 87, 87, 2661, 4117, - - 2655, 2665, 87, 87, 2658, 87, 87, 2659, 87, 2663, - 87, 2660, 2664, 2669, 2666, 2667, 87, 87, 87, 2662, - 87, 2670, 87, 87, 2672, 2668, 2671, 87, 2673, 2675, - 87, 2681, 87, 2676, 87, 2677, 2678, 2683, 87, 2680, - 87, 2674, 87, 2682, 87, 87, 87, 87, 2686, 87, - 2687, 87, 2679, 175, 2692, 87, 87, 2696, 2684, 2688, - 87, 2685, 2689, 87, 2699, 87, 2694, 2697, 2698, 2690, - 2691, 2695, 87, 87, 87, 2693, 87, 87, 2702, 2704, - 87, 87, 87, 2705, 2709, 87, 87, 2710, 87, 87, - 2708, 87, 87, 2714, 2700, 2703, 2701, 2706, 2713, 87, - - 2711, 87, 87, 4117, 87, 87, 2715, 2712, 2707, 2717, - 87, 2719, 2720, 87, 87, 87, 2722, 87, 87, 2721, - 2718, 2716, 87, 87, 87, 2724, 87, 2723, 2725, 87, - 87, 2728, 87, 87, 87, 2726, 87, 2732, 87, 87, - 87, 2729, 2727, 2736, 2730, 2738, 87, 87, 2731, 87, - 2734, 2733, 2741, 2739, 87, 2740, 2735, 87, 87, 87, - 87, 2737, 87, 87, 87, 2750, 87, 2747, 87, 87, - 87, 2745, 2742, 87, 87, 87, 2744, 2748, 2751, 2746, - 4117, 2749, 87, 2743, 87, 87, 87, 2752, 2753, 2761, - 2763, 87, 2754, 87, 87, 87, 87, 2755, 2759, 2756, - - 2762, 2757, 87, 87, 87, 2758, 2760, 2765, 2764, 2767, - 87, 87, 2768, 2770, 87, 87, 2766, 87, 87, 87, - 2771, 2772, 4117, 87, 2769, 87, 2777, 2778, 87, 87, - 2773, 2779, 87, 2775, 87, 2774, 2776, 2780, 87, 87, - 87, 2784, 2786, 87, 2785, 87, 2787, 2781, 87, 2782, - 87, 2789, 2783, 87, 2792, 87, 2793, 87, 87, 87, - 87, 87, 2790, 2788, 2794, 2791, 2795, 87, 87, 2800, - 87, 2801, 87, 87, 2803, 87, 87, 87, 2796, 2798, - 2797, 2799, 2805, 87, 87, 87, 2808, 87, 2809, 87, - 2807, 2810, 2802, 87, 2804, 87, 87, 2813, 87, 2806, - - 87, 87, 2811, 2815, 87, 87, 2819, 87, 87, 87, - 2818, 87, 2816, 2821, 87, 2812, 87, 2814, 87, 87, - 2817, 2823, 2825, 87, 2824, 87, 2826, 2820, 2829, 2822, - 2828, 87, 87, 87, 2831, 87, 2834, 87, 2830, 2835, - 87, 2827, 87, 87, 87, 87, 87, 87, 2832, 87, - 2840, 2841, 87, 87, 2833, 87, 87, 2837, 87, 2839, - 2836, 2845, 2846, 87, 2852, 87, 2838, 2843, 2842, 87, - 2851, 87, 2847, 2844, 2854, 87, 87, 87, 2853, 87, - 87, 2848, 87, 2856, 2868, 2855, 2860, 87, 2849, 2850, - 87, 2857, 87, 2862, 87, 87, 2863, 2858, 2859, 87, - - 87, 2864, 87, 2865, 87, 87, 2869, 2870, 2861, 2871, - 2872, 87, 87, 87, 87, 87, 2875, 87, 2866, 2877, - 2867, 87, 2876, 87, 87, 2874, 2879, 2883, 2880, 2881, - 87, 2884, 2882, 87, 87, 87, 2873, 87, 2887, 87, - 2888, 2878, 87, 87, 87, 87, 87, 2889, 2892, 2886, - 87, 2885, 87, 87, 87, 87, 2891, 87, 87, 2894, - 4117, 2895, 2896, 2897, 2890, 2899, 2893, 2900, 87, 2898, - 87, 87, 2901, 87, 87, 2905, 2906, 2902, 2903, 2904, - 87, 2907, 87, 87, 87, 87, 2910, 87, 175, 2908, - 87, 2912, 87, 2913, 2909, 87, 2911, 2918, 87, 87, - - 87, 87, 87, 87, 87, 2914, 87, 2915, 2916, 2920, - 2921, 2917, 2922, 87, 2919, 2924, 87, 2926, 2923, 87, - 87, 87, 2925, 2928, 2929, 87, 87, 87, 2927, 2933, - 87, 2934, 87, 87, 2931, 2935, 87, 2955, 2932, 87, - 2937, 2930, 2938, 87, 87, 87, 2941, 2936, 2939, 2940, - 2942, 87, 87, 2944, 87, 87, 87, 87, 2946, 87, - 2943, 87, 2948, 87, 87, 87, 2951, 2952, 87, 2945, - 87, 2947, 87, 87, 87, 2954, 87, 2949, 87, 2956, - 2957, 87, 2953, 2950, 87, 87, 87, 2960, 87, 2958, - 2959, 87, 2962, 87, 2967, 2961, 2966, 2963, 2964, 87, - - 87, 2965, 87, 87, 87, 87, 87, 2974, 2971, 87, - 87, 2973, 87, 87, 87, 2975, 87, 2970, 87, 2976, - 2968, 2977, 2969, 87, 2978, 2972, 87, 87, 2979, 2984, - 87, 2980, 2982, 2981, 87, 87, 87, 2988, 2989, 87, - 87, 2987, 87, 87, 87, 87, 2985, 2983, 2990, 87, - 87, 2986, 2991, 2993, 2992, 87, 2994, 87, 2995, 87, - 87, 2997, 2996, 87, 2999, 87, 2998, 87, 3000, 87, - 3002, 3003, 3004, 87, 3006, 87, 87, 87, 87, 87, - 87, 3001, 3009, 87, 3008, 3005, 3007, 87, 87, 87, - 87, 3015, 87, 3013, 3010, 87, 3012, 87, 87, 3020, - - 87, 3011, 3018, 3019, 3021, 87, 3022, 87, 87, 3024, - 3016, 87, 87, 87, 87, 3014, 3017, 87, 87, 3027, - 87, 3029, 87, 3032, 87, 87, 87, 3023, 87, 3025, - 87, 87, 3030, 3026, 3031, 3034, 3028, 3035, 3036, 3039, - 87, 3033, 87, 87, 87, 3038, 3037, 87, 87, 87, - 3042, 3040, 3041, 87, 87, 3043, 87, 87, 87, 3046, - 87, 87, 87, 3044, 3045, 3047, 87, 3052, 3053, 87, - 87, 4117, 87, 3057, 87, 3054, 3048, 3049, 3050, 3051, - 3055, 3056, 87, 87, 87, 3059, 87, 3058, 3060, 87, - 87, 3063, 87, 87, 87, 3067, 87, 87, 3061, 3066, - - 87, 3062, 3069, 87, 3070, 87, 3071, 87, 3068, 3072, - 3064, 87, 3065, 3073, 87, 87, 3076, 87, 3074, 3075, - 87, 3077, 87, 3078, 87, 87, 87, 87, 4117, 3079, - 87, 87, 3085, 87, 3087, 87, 87, 3081, 3088, 87, - 87, 3090, 87, 87, 3080, 87, 3082, 3084, 3083, 3086, - 87, 3089, 3092, 87, 87, 3091, 3094, 87, 3095, 3098, - 87, 87, 3093, 3100, 87, 87, 87, 87, 87, 87, - 3099, 87, 87, 87, 3096, 175, 87, 3097, 3109, 87, - 3103, 3106, 87, 3105, 87, 3107, 3102, 3110, 87, 3111, - 87, 3101, 3104, 3108, 3113, 87, 87, 3114, 87, 3112, - - 3119, 87, 3115, 3118, 87, 87, 87, 87, 3121, 87, - 3125, 87, 3123, 87, 3124, 3126, 87, 3116, 3117, 87, - 3122, 87, 3128, 87, 3130, 3127, 87, 3120, 3129, 87, - 3131, 87, 87, 87, 87, 87, 87, 87, 87, 87, - 87, 87, 3133, 3143, 3132, 87, 87, 3141, 3135, 87, - 87, 3134, 4117, 3137, 3136, 87, 3147, 3139, 3138, 3140, - 3142, 87, 87, 87, 3145, 3144, 3148, 3146, 3149, 87, - 87, 87, 3151, 3153, 87, 3150, 3155, 87, 87, 3152, - 3154, 3156, 87, 87, 87, 87, 87, 87, 87, 87, - 3159, 87, 3165, 87, 87, 3166, 3157, 3168, 87, 3160, - - 3158, 3167, 87, 3161, 3162, 3163, 3164, 3169, 87, 87, - 3173, 87, 3175, 3170, 87, 3172, 3174, 87, 87, 87, - 3171, 87, 87, 87, 87, 3182, 87, 87, 3181, 87, - 87, 87, 3176, 87, 87, 87, 3178, 3177, 3180, 87, - 3189, 3179, 3186, 87, 3187, 3190, 87, 3183, 3192, 3184, - 3185, 3191, 87, 87, 3188, 3193, 87, 87, 3194, 3195, - 87, 87, 3196, 87, 87, 3201, 87, 87, 87, 3200, - 87, 87, 87, 3198, 87, 3203, 3197, 87, 87, 3209, - 87, 3208, 87, 3199, 3212, 87, 87, 3202, 3204, 3210, - 3205, 87, 3206, 87, 87, 3207, 87, 3213, 3215, 87, - - 3211, 3220, 87, 87, 87, 3218, 3214, 3219, 3216, 87, - 87, 3217, 87, 3225, 87, 87, 87, 3221, 87, 87, - 87, 87, 3222, 3223, 87, 3228, 87, 3224, 3226, 3227, - 87, 3243, 3230, 87, 3229, 3235, 87, 87, 3233, 87, - 3231, 3234, 87, 3232, 87, 3236, 3237, 87, 3238, 87, - 3239, 3240, 87, 3242, 87, 87, 3244, 87, 3241, 3248, - 87, 87, 3247, 87, 3250, 87, 87, 3253, 87, 3246, - 87, 3245, 87, 87, 3251, 87, 3260, 87, 87, 87, - 87, 87, 3249, 3254, 3257, 3255, 3256, 3258, 3252, 3259, - 3263, 87, 87, 87, 87, 87, 3262, 3264, 3265, 3261, - - 3267, 87, 87, 87, 87, 87, 87, 87, 3266, 3268, - 87, 3273, 3270, 3271, 87, 3274, 3276, 87, 87, 3272, - 87, 3269, 3275, 3277, 87, 3278, 87, 3282, 175, 3279, - 87, 3280, 87, 87, 87, 3284, 3287, 3281, 87, 3283, - 87, 87, 87, 3288, 87, 3289, 87, 3291, 87, 3294, - 87, 3285, 3286, 3293, 87, 3290, 3295, 87, 87, 3292, - 87, 3299, 87, 3296, 3301, 87, 87, 3297, 3300, 3302, - 87, 3303, 87, 87, 3298, 3306, 87, 3304, 87, 87, - 3307, 87, 87, 3308, 3309, 87, 87, 3305, 87, 3314, - 3315, 3310, 87, 87, 3312, 87, 87, 3316, 3318, 87, - - 3311, 87, 87, 87, 87, 3317, 3321, 3320, 3319, 3313, - 87, 87, 87, 87, 87, 3323, 3322, 3324, 3325, 87, - 3333, 87, 87, 3330, 87, 87, 87, 3327, 3328, 3326, - 3329, 87, 87, 3331, 3336, 3332, 87, 3334, 87, 87, - 87, 87, 3337, 3335, 87, 3342, 87, 87, 87, 87, - 87, 87, 87, 3347, 3343, 87, 87, 3338, 3345, 3339, - 3346, 3340, 87, 3341, 3349, 3348, 87, 3344, 3351, 87, - 87, 3350, 87, 3356, 87, 87, 3355, 3358, 3359, 87, - 4117, 3352, 3362, 87, 87, 3353, 3354, 87, 87, 3363, - 87, 87, 87, 87, 87, 87, 87, 3369, 3360, 3364, - - 3357, 3366, 3367, 87, 87, 3361, 87, 3368, 3371, 3370, - 87, 3374, 87, 3372, 87, 87, 3376, 3365, 87, 87, - 87, 87, 87, 3377, 3373, 3378, 87, 87, 87, 3375, - 3385, 87, 87, 3384, 3380, 3382, 3381, 3379, 3387, 87, - 3388, 87, 3389, 87, 87, 87, 87, 87, 3390, 3383, - 3391, 3393, 87, 87, 3397, 3386, 3392, 87, 3395, 3398, - 87, 87, 87, 87, 87, 4117, 3394, 87, 3403, 3396, - 3404, 87, 87, 3399, 3405, 87, 3406, 87, 87, 87, - 87, 3407, 3400, 3401, 3402, 3408, 3410, 87, 87, 3413, - 87, 87, 3409, 87, 3414, 3415, 87, 87, 3411, 3417, - - 87, 87, 87, 3421, 3422, 87, 3416, 87, 3412, 87, - 3418, 3423, 3424, 87, 87, 3427, 3420, 3425, 87, 3419, - 87, 87, 87, 3426, 3429, 87, 87, 3428, 87, 3430, - 87, 3435, 3434, 3436, 3432, 3437, 3431, 87, 87, 87, - 87, 87, 3439, 3440, 87, 3433, 3441, 87, 87, 87, - 87, 87, 3448, 3438, 3442, 3443, 87, 87, 3444, 3445, - 3447, 87, 87, 87, 87, 3446, 87, 3451, 3453, 87, - 3456, 87, 87, 87, 87, 87, 87, 3458, 3449, 3450, - 3455, 3452, 87, 3463, 3454, 3459, 3457, 3460, 3464, 87, - 3462, 3465, 3468, 87, 3461, 3467, 3466, 87, 87, 3469, - - 87, 3470, 87, 3471, 87, 3472, 87, 3473, 87, 87, - 87, 87, 87, 87, 3475, 87, 87, 87, 87, 87, - 3479, 3478, 3481, 3483, 3474, 87, 87, 87, 3484, 3480, - 3476, 3488, 87, 3489, 87, 3482, 87, 3477, 87, 3490, - 3492, 87, 87, 87, 87, 3485, 3486, 3487, 3493, 3494, - 3496, 87, 87, 3491, 3498, 87, 87, 87, 87, 3497, - 87, 3495, 3499, 3500, 87, 3501, 87, 3502, 3503, 87, - 87, 3507, 87, 3508, 87, 3504, 87, 87, 3506, 3505, - 3509, 87, 87, 87, 87, 3515, 3510, 87, 87, 87, - 3516, 87, 87, 3512, 87, 87, 3518, 3596, 3513, 3521, - - 3511, 3517, 87, 3522, 3514, 87, 87, 3519, 87, 3520, - 3523, 3524, 87, 87, 87, 3529, 87, 3525, 87, 3528, - 87, 3526, 3531, 87, 87, 87, 3535, 87, 3527, 3536, - 87, 87, 3530, 3538, 3532, 87, 87, 87, 87, 87, - 3537, 87, 3541, 3534, 87, 3544, 87, 3539, 87, 3533, - 3542, 87, 87, 3547, 87, 3549, 3545, 3548, 3543, 87, - 87, 3540, 87, 87, 87, 3551, 87, 3546, 3550, 87, - 3556, 3558, 87, 3557, 3553, 87, 3552, 3554, 3559, 87, - 3555, 3560, 87, 87, 3561, 87, 87, 87, 87, 3567, - 87, 3566, 3568, 87, 87, 87, 87, 3571, 87, 3569, - - 87, 3570, 87, 3562, 87, 3563, 3564, 3565, 3572, 3575, - 87, 3577, 3573, 87, 3579, 87, 87, 87, 87, 87, - 3580, 87, 87, 3574, 3581, 87, 3582, 87, 3576, 87, - 3583, 87, 3588, 87, 87, 3589, 87, 3584, 3578, 87, - 3585, 87, 3586, 3592, 87, 87, 87, 3590, 87, 3591, - 3593, 3587, 87, 3597, 87, 87, 87, 3601, 87, 87, - 3594, 3605, 87, 3602, 3595, 87, 3598, 3599, 3606, 87, - 87, 87, 3600, 3608, 87, 4117, 3603, 3611, 3609, 87, - 3612, 87, 3613, 87, 3607, 3604, 3615, 87, 3610, 87, - 87, 3614, 87, 87, 87, 3621, 87, 3618, 87, 3620, - - 87, 87, 3624, 3626, 87, 3616, 3617, 87, 87, 3619, - 3623, 87, 3628, 87, 87, 87, 87, 87, 3622, 87, - 3634, 87, 3635, 3625, 87, 87, 3627, 3629, 3640, 87, - 3633, 3639, 87, 87, 87, 3630, 3631, 3642, 3632, 87, - 87, 87, 3636, 87, 3643, 87, 3637, 3638, 3646, 87, - 3647, 87, 87, 3641, 3650, 87, 87, 87, 87, 87, - 3648, 87, 3644, 3655, 87, 3653, 87, 3645, 3652, 87, - 87, 3657, 3649, 3663, 3651, 3659, 87, 87, 3654, 87, - 3656, 3662, 3660, 87, 3658, 3661, 87, 87, 87, 3665, - 3664, 3666, 87, 87, 3670, 3671, 87, 87, 3669, 87, - - 87, 3673, 3672, 3667, 87, 3676, 87, 87, 87, 3675, - 87, 3679, 3668, 3677, 87, 3674, 87, 87, 3682, 87, - 87, 87, 87, 3687, 87, 87, 87, 87, 3683, 3678, - 87, 3680, 3681, 3691, 87, 3686, 3690, 87, 3684, 3692, - 87, 87, 3689, 3703, 3688, 87, 3685, 3693, 87, 87, - 3694, 3695, 3697, 87, 3696, 3698, 87, 3699, 87, 87, - 3702, 87, 3701, 87, 3705, 87, 87, 87, 3700, 87, - 87, 3706, 3707, 87, 3709, 87, 3710, 87, 87, 87, - 87, 3708, 87, 3716, 3717, 87, 3711, 87, 87, 3704, - 87, 3712, 87, 4117, 87, 3723, 87, 87, 3714, 87, - - 3713, 87, 3715, 3722, 3720, 3726, 87, 3719, 87, 3730, - 87, 87, 3721, 3718, 3727, 87, 87, 3724, 87, 3725, - 3729, 3728, 3732, 3734, 87, 87, 87, 87, 87, 87, - 3737, 3731, 3738, 87, 3733, 3740, 87, 3741, 87, 87, - 87, 87, 3744, 87, 3735, 3736, 3742, 3743, 87, 3739, - 87, 3745, 3747, 87, 87, 87, 87, 87, 3746, 3748, - 3749, 3750, 87, 3752, 87, 87, 87, 3751, 3755, 3754, - 87, 87, 87, 87, 87, 3753, 3758, 3756, 87, 3759, - 87, 87, 87, 87, 3757, 87, 87, 87, 3768, 3771, - 3769, 3760, 3772, 3761, 3762, 87, 3763, 3764, 87, 3765, - - 3766, 3767, 87, 87, 87, 3774, 3770, 3776, 87, 3777, - 87, 87, 87, 3781, 87, 3778, 3775, 3780, 3773, 3779, - 87, 87, 3784, 87, 87, 3782, 3786, 87, 3787, 3788, - 87, 87, 3789, 3790, 3794, 87, 3791, 87, 87, 3785, - 3783, 3792, 3793, 3795, 87, 87, 3797, 87, 87, 87, - 3800, 87, 3801, 87, 3796, 3802, 3803, 87, 3804, 3807, - 87, 87, 87, 3799, 87, 3805, 3798, 3808, 87, 87, - 3809, 87, 87, 3806, 87, 3813, 87, 87, 87, 3812, - 87, 87, 87, 87, 87, 87, 3818, 87, 3817, 3822, - 4117, 3810, 3811, 3819, 87, 3814, 3824, 87, 3815, 3823, - - 3820, 3821, 87, 87, 3826, 3816, 3827, 87, 3828, 87, - 87, 3825, 3829, 87, 87, 87, 87, 3835, 3837, 87, - 3832, 87, 3836, 87, 87, 3833, 87, 87, 3834, 3831, - 87, 3845, 3830, 87, 4117, 3841, 3839, 87, 3842, 3844, - 87, 87, 87, 87, 3838, 87, 3843, 3840, 3846, 3847, - 87, 3848, 87, 87, 3851, 87, 3849, 3852, 3850, 3853, - 87, 3854, 87, 87, 87, 3857, 87, 3858, 87, 3859, - 87, 3865, 3855, 3860, 87, 3861, 87, 3862, 87, 3863, - 87, 87, 3856, 3864, 87, 3867, 87, 87, 87, 87, - 3866, 87, 87, 3870, 87, 3872, 3874, 87, 87, 87, - - 87, 3875, 3879, 87, 87, 87, 3871, 3868, 3869, 3873, - 3876, 3881, 87, 87, 87, 3878, 87, 87, 3885, 3877, - 3882, 87, 87, 3880, 3887, 87, 3883, 3890, 3884, 3888, - 3889, 87, 87, 3886, 87, 87, 87, 3892, 87, 3894, - 87, 3897, 87, 3896, 87, 87, 87, 87, 87, 3899, - 3891, 87, 87, 87, 3895, 87, 3898, 3903, 87, 3905, - 87, 3893, 3902, 4117, 3900, 87, 3901, 3904, 3906, 87, - 3907, 87, 87, 87, 3912, 3911, 3910, 87, 3908, 3914, - 3909, 87, 3913, 87, 87, 87, 87, 3920, 87, 3921, - 87, 3922, 87, 3923, 87, 87, 87, 3919, 87, 3926, - - 3915, 87, 3916, 3917, 3918, 3925, 87, 3930, 3924, 87, - 87, 87, 87, 87, 87, 3936, 3928, 3933, 3927, 87, - 3929, 3932, 87, 87, 3934, 87, 3935, 87, 87, 87, - 87, 87, 3931, 87, 87, 87, 3937, 87, 3938, 3945, - 3943, 3944, 3948, 3939, 3940, 3942, 87, 3947, 3950, 87, - 87, 87, 3941, 87, 3946, 3954, 87, 87, 87, 87, - 87, 87, 87, 3959, 3952, 3949, 3953, 87, 3957, 4117, - 3951, 3962, 87, 87, 3965, 87, 3960, 3955, 3956, 87, - 87, 3958, 3963, 3964, 3966, 87, 3967, 3961, 3968, 87, - 3969, 87, 87, 87, 87, 87, 87, 3972, 87, 87, - - 3973, 3974, 3977, 87, 87, 87, 3981, 87, 87, 87, - 3980, 3970, 4117, 3971, 3976, 87, 3979, 3978, 3983, 87, - 3984, 87, 87, 3975, 3985, 87, 3986, 87, 87, 3982, - 87, 3989, 87, 3987, 87, 3988, 3991, 87, 3990, 3992, - 87, 3994, 3995, 87, 87, 87, 87, 87, 87, 3993, - 4000, 87, 87, 4001, 87, 4004, 3997, 4005, 87, 3996, - 87, 87, 4002, 87, 87, 3999, 87, 4003, 4010, 87, - 3998, 4009, 4006, 4007, 4011, 87, 87, 87, 87, 87, - 87, 87, 87, 4008, 4018, 87, 87, 87, 4117, 87, - 4020, 4012, 4013, 4014, 4017, 87, 87, 87, 4019, 87, - - 4015, 4016, 4022, 4029, 87, 87, 87, 4021, 4023, 4024, - 4027, 4028, 4025, 87, 4026, 87, 87, 87, 87, 87, - 87, 4037, 87, 87, 4039, 4036, 87, 4040, 4038, 87, - 87, 87, 87, 4117, 4030, 4032, 4031, 4034, 4033, 4035, - 87, 87, 87, 4045, 87, 4041, 4042, 4043, 4044, 87, - 87, 4046, 4047, 87, 4048, 4049, 87, 87, 4050, 4051, - 87, 4053, 4052, 87, 87, 87, 87, 4058, 87, 4117, - 87, 4055, 4117, 87, 4061, 87, 4062, 87, 4063, 87, - 87, 4064, 4054, 4060, 4056, 4057, 87, 4059, 4066, 87, - 87, 4065, 87, 87, 87, 87, 87, 4069, 87, 4067, - - 87, 4073, 4068, 4074, 87, 87, 87, 87, 4072, 4075, - 4076, 4117, 4070, 4071, 87, 4078, 87, 4080, 87, 4081, - 87, 87, 4085, 87, 4079, 4082, 4084, 4117, 4083, 87, - 4077, 4086, 87, 87, 4087, 4088, 4089, 87, 87, 87, - 87, 87, 87, 4095, 87, 4090, 4091, 4093, 87, 87, - 87, 87, 87, 87, 4097, 4098, 87, 4101, 87, 4092, - 4094, 4102, 87, 87, 4105, 4106, 87, 4096, 87, 87, - 4099, 4100, 4103, 4108, 87, 4107, 4110, 4104, 4109, 87, - 87, 87, 87, 87, 4117, 4111, 4112, 4115, 87, 4116, - 87, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, 4117, - - 4117, 4113, 4114, 48, 48, 48, 48, 48, 48, 48, + 87, 87, 180, 501, 492, 87, 506, 477, 482, 87, + 87, 507, 87, 483, 502, 87, 491, 503, 484, 517, + 87, 485, 504, 505, 510, 87, 486, 487, 488, 489, + 87, 508, 175, 493, 87, 494, 87, 495, 87, 509, + 523, 87, 87, 87, 87, 519, 87, 496, 497, 498, + 499, 500, 87, 518, 87, 511, 513, 514, 512, 520, + 515, 516, 87, 521, 87, 522, 87, 524, 526, 87, + + 87, 525, 87, 87, 87, 87, 531, 87, 87, 538, + 537, 527, 87, 87, 532, 87, 533, 87, 530, 528, + 87, 87, 529, 87, 622, 534, 539, 536, 540, 550, + 87, 544, 535, 542, 541, 543, 545, 87, 87, 551, + 546, 552, 87, 553, 87, 87, 87, 87, 87, 87, + 554, 568, 87, 547, 173, 175, 548, 87, 549, 87, + 555, 87, 556, 87, 570, 87, 567, 571, 557, 569, + 87, 572, 558, 573, 587, 575, 593, 559, 586, 87, + 560, 87, 561, 171, 562, 588, 590, 87, 87, 574, + 589, 87, 87, 87, 591, 87, 596, 563, 594, 87, + + 564, 592, 565, 598, 566, 87, 87, 576, 577, 87, + 595, 87, 597, 578, 87, 87, 87, 579, 580, 581, + 582, 583, 87, 170, 584, 600, 601, 585, 602, 599, + 603, 609, 87, 87, 87, 607, 87, 605, 610, 611, + 604, 87, 608, 613, 87, 614, 87, 87, 87, 87, + 87, 87, 620, 87, 87, 606, 612, 87, 87, 616, + 87, 87, 618, 87, 87, 623, 615, 87, 617, 619, + 624, 625, 632, 87, 626, 630, 87, 627, 621, 628, + 629, 87, 87, 631, 633, 634, 87, 87, 87, 639, + 636, 637, 87, 87, 87, 640, 87, 655, 87, 87, + + 87, 87, 635, 87, 658, 87, 638, 641, 656, 642, + 644, 87, 643, 645, 646, 87, 657, 660, 87, 661, + 87, 666, 663, 87, 659, 647, 662, 648, 87, 87, + 87, 87, 664, 649, 87, 665, 87, 667, 669, 87, + 87, 650, 651, 87, 668, 652, 653, 87, 671, 654, + 87, 673, 674, 670, 87, 677, 87, 87, 87, 675, + 672, 676, 87, 87, 87, 681, 87, 679, 680, 87, + 87, 87, 682, 683, 87, 87, 87, 678, 684, 688, + 87, 87, 87, 687, 87, 691, 689, 692, 686, 685, + 87, 87, 87, 696, 694, 87, 690, 87, 699, 693, + + 697, 87, 701, 695, 87, 698, 87, 702, 87, 87, + 87, 87, 87, 87, 87, 87, 87, 704, 708, 87, + 706, 87, 87, 700, 715, 703, 717, 710, 87, 87, + 87, 705, 87, 707, 709, 716, 714, 711, 720, 712, + 713, 87, 721, 87, 718, 87, 722, 719, 87, 87, + 87, 87, 726, 724, 87, 730, 725, 723, 87, 87, + 87, 87, 732, 729, 727, 733, 728, 87, 87, 87, + 87, 87, 736, 739, 735, 87, 87, 87, 731, 87, + 87, 741, 743, 87, 87, 87, 87, 87, 168, 734, + 737, 738, 740, 87, 742, 87, 744, 746, 87, 758, + + 87, 779, 745, 87, 747, 755, 759, 756, 757, 748, + 87, 749, 87, 87, 761, 760, 762, 750, 87, 751, + 87, 87, 752, 753, 87, 767, 763, 87, 765, 754, + 764, 766, 772, 771, 769, 87, 87, 770, 87, 776, + 87, 87, 774, 773, 87, 768, 87, 781, 87, 87, + 87, 775, 87, 784, 87, 786, 87, 87, 87, 87, + 783, 778, 87, 777, 782, 785, 87, 789, 790, 780, + 87, 791, 87, 87, 87, 787, 87, 792, 794, 788, + 797, 793, 175, 796, 799, 795, 798, 87, 87, 87, + 87, 87, 804, 87, 87, 87, 87, 87, 87, 800, + + 807, 813, 87, 801, 809, 803, 87, 87, 802, 805, + 808, 806, 812, 87, 811, 87, 815, 816, 87, 810, + 87, 87, 87, 87, 818, 87, 87, 814, 87, 87, + 817, 821, 822, 87, 819, 87, 823, 87, 166, 87, + 820, 832, 87, 829, 825, 833, 87, 824, 830, 87, + 835, 826, 831, 828, 827, 834, 87, 87, 836, 87, + 837, 87, 838, 87, 839, 87, 87, 87, 87, 840, + 87, 87, 845, 87, 844, 87, 87, 87, 843, 848, + 87, 841, 849, 847, 87, 87, 842, 853, 852, 87, + 87, 87, 846, 87, 855, 87, 857, 87, 87, 859, + + 87, 87, 87, 850, 851, 87, 866, 862, 87, 854, + 87, 858, 87, 856, 87, 860, 87, 87, 87, 867, + 87, 874, 861, 87, 863, 87, 864, 959, 865, 87, + 868, 87, 869, 87, 87, 873, 875, 870, 877, 876, + 871, 872, 87, 87, 882, 879, 881, 878, 87, 880, + 87, 87, 87, 87, 884, 87, 885, 883, 87, 87, + 888, 889, 87, 87, 890, 87, 87, 87, 87, 87, + 898, 87, 887, 893, 896, 87, 87, 87, 886, 891, + 892, 895, 87, 894, 899, 87, 87, 897, 87, 905, + 902, 87, 901, 87, 87, 900, 87, 87, 909, 87, + + 904, 916, 907, 903, 87, 910, 908, 906, 87, 912, + 913, 911, 87, 914, 87, 87, 87, 915, 87, 87, + 87, 922, 87, 87, 920, 924, 87, 87, 923, 925, + 918, 87, 919, 917, 87, 87, 929, 87, 87, 921, + 927, 930, 87, 87, 87, 87, 87, 926, 941, 87, + 928, 931, 932, 933, 87, 943, 934, 87, 87, 87, + 935, 87, 936, 944, 942, 87, 946, 87, 947, 937, + 87, 87, 951, 949, 948, 938, 939, 940, 87, 945, + 87, 955, 87, 952, 87, 953, 956, 87, 950, 87, + 957, 87, 87, 961, 87, 954, 87, 87, 87, 87, + + 968, 87, 87, 960, 87, 969, 87, 958, 87, 87, + 87, 970, 963, 962, 964, 965, 87, 966, 87, 967, + 978, 975, 973, 971, 972, 87, 87, 87, 87, 974, + 976, 977, 87, 87, 87, 87, 87, 87, 87, 985, + 981, 980, 87, 87, 87, 979, 87, 87, 996, 87, + 183, 982, 987, 984, 983, 986, 988, 989, 87, 87, + 87, 990, 991, 992, 994, 993, 87, 87, 999, 87, + 997, 87, 995, 87, 998, 87, 1002, 87, 1000, 87, + 87, 87, 87, 1001, 87, 1007, 1006, 87, 87, 1003, + 1005, 1009, 1011, 1012, 1004, 87, 87, 87, 87, 87, + + 1008, 87, 87, 1014, 87, 175, 1010, 1016, 1018, 1015, + 1022, 1019, 1021, 1013, 87, 1017, 1020, 1023, 87, 87, + 87, 87, 87, 1024, 87, 87, 87, 1028, 1031, 87, + 1026, 87, 1032, 87, 1025, 87, 1034, 1027, 1036, 1029, + 1033, 1035, 87, 87, 1037, 1039, 87, 1030, 87, 87, + 87, 87, 87, 1042, 87, 1046, 87, 1047, 87, 87, + 87, 87, 1038, 87, 1043, 1040, 1048, 1050, 1041, 87, + 87, 1049, 1045, 87, 87, 1044, 1062, 1051, 87, 87, + 87, 87, 87, 87, 87, 181, 1065, 1064, 1061, 1067, + 1053, 1063, 87, 1068, 1052, 87, 1070, 1054, 1069, 87, + + 1055, 87, 1071, 1066, 1056, 87, 1072, 1057, 87, 87, + 1073, 87, 1077, 180, 1058, 1059, 87, 1060, 87, 87, + 87, 1087, 87, 1075, 87, 87, 1074, 87, 1090, 87, + 87, 1076, 87, 1078, 1079, 1094, 1080, 1089, 87, 1081, + 1086, 87, 1092, 1088, 1082, 87, 1095, 87, 1099, 1091, + 1083, 1084, 1096, 1085, 1098, 1100, 1097, 87, 1093, 87, + 1101, 87, 87, 1103, 1102, 87, 87, 1106, 87, 87, + 1105, 87, 1108, 1107, 1104, 87, 1109, 1110, 87, 87, + 87, 1111, 87, 87, 87, 87, 1114, 1112, 87, 87, + 1119, 87, 87, 1118, 87, 87, 1123, 87, 87, 1113, + + 87, 1115, 175, 1127, 1116, 87, 1120, 1117, 1122, 87, + 1125, 87, 1121, 87, 87, 1124, 1128, 87, 1129, 1130, + 87, 1131, 1126, 87, 1134, 1138, 1132, 87, 1133, 87, + 87, 1135, 1136, 87, 1140, 1142, 1137, 87, 87, 87, + 87, 87, 1141, 87, 1144, 87, 1143, 1139, 1146, 87, + 1147, 87, 87, 1145, 87, 87, 87, 1148, 87, 1152, + 1149, 1151, 87, 87, 87, 1153, 1157, 87, 87, 1161, + 87, 87, 1150, 1160, 87, 87, 87, 1158, 1159, 1155, + 1154, 87, 87, 1156, 87, 87, 87, 87, 87, 1162, + 1164, 87, 87, 87, 1167, 1163, 1171, 1172, 87, 87, + + 1165, 1168, 1173, 1170, 87, 87, 87, 1174, 87, 87, + 1166, 1169, 1176, 1175, 1178, 1180, 87, 1183, 87, 1179, + 1181, 87, 87, 1182, 1177, 87, 87, 87, 87, 87, + 87, 1189, 1191, 1184, 1186, 1192, 87, 87, 87, 1190, + 87, 1185, 87, 1194, 87, 1188, 87, 1196, 87, 1197, + 1187, 87, 87, 87, 87, 87, 1206, 1201, 1193, 1203, + 87, 1195, 87, 87, 1198, 87, 87, 87, 1199, 1209, + 87, 1200, 1204, 87, 1207, 1202, 1212, 87, 1208, 1205, + 87, 1211, 1210, 87, 87, 1213, 87, 1214, 1215, 1216, + 87, 87, 87, 87, 87, 1219, 87, 87, 87, 1217, + + 1221, 87, 87, 1228, 1218, 87, 1229, 87, 1755, 87, + 87, 1220, 87, 1222, 1223, 87, 1225, 1231, 1224, 1230, + 1234, 1226, 1227, 87, 1232, 1235, 87, 1233, 87, 87, + 87, 87, 1236, 87, 1237, 1240, 87, 1242, 87, 1244, + 87, 1238, 1245, 1246, 87, 87, 1243, 87, 87, 1239, + 1249, 87, 87, 87, 1241, 87, 87, 1252, 87, 87, + 1248, 1250, 1247, 87, 1255, 87, 1254, 87, 1256, 1259, + 87, 1251, 87, 1253, 1260, 175, 1262, 87, 1261, 87, + 1263, 1257, 87, 1258, 87, 87, 87, 1267, 87, 1264, + 1265, 1271, 1266, 87, 87, 87, 87, 87, 1283, 87, + + 1270, 1282, 1272, 1268, 87, 87, 1273, 87, 1284, 1269, + 87, 1286, 87, 87, 1274, 87, 1275, 87, 1294, 87, + 1276, 1293, 1277, 1292, 1287, 1285, 1278, 87, 1279, 87, + 87, 1288, 1289, 1280, 1291, 1290, 1296, 87, 1281, 1298, + 87, 1297, 87, 1295, 1300, 87, 87, 87, 1303, 87, + 87, 1299, 1304, 87, 1307, 87, 1301, 87, 1306, 87, + 1302, 173, 1305, 1314, 1308, 1309, 87, 87, 1312, 1311, + 87, 1316, 1313, 1317, 1310, 1315, 1320, 87, 1319, 87, + 1318, 87, 87, 87, 87, 87, 87, 87, 87, 87, + 87, 87, 1335, 1332, 87, 87, 87, 87, 1331, 1336, + + 87, 87, 1334, 1333, 1322, 1323, 1321, 87, 1324, 1337, + 1338, 1339, 87, 1325, 1340, 1326, 1341, 1344, 87, 87, + 87, 1327, 87, 87, 1345, 87, 1328, 1329, 87, 87, + 87, 1342, 1346, 1330, 1343, 1351, 87, 1354, 87, 87, + 1347, 1348, 1352, 87, 87, 87, 1349, 1350, 1355, 1357, + 1353, 87, 87, 1359, 87, 87, 87, 1360, 1356, 87, + 87, 1365, 87, 87, 1358, 1362, 87, 87, 87, 1363, + 87, 1364, 1367, 1361, 87, 1369, 87, 87, 1372, 87, + 87, 87, 87, 1366, 87, 1368, 1380, 1377, 1370, 1375, + 1371, 1374, 87, 1376, 1373, 87, 1379, 87, 87, 1378, + + 87, 87, 1384, 87, 87, 1387, 87, 87, 87, 1386, + 87, 87, 1382, 1381, 87, 87, 87, 1418, 87, 87, + 1383, 1393, 1390, 1394, 1395, 1388, 1389, 87, 1385, 87, + 1392, 87, 1391, 1399, 1396, 1400, 1397, 87, 1398, 87, + 1401, 87, 87, 87, 87, 1405, 87, 171, 87, 1407, + 1406, 87, 1408, 87, 87, 87, 1403, 1402, 1410, 87, + 1404, 1409, 87, 87, 1413, 87, 87, 1411, 87, 87, + 87, 87, 1423, 87, 1412, 87, 1415, 1416, 87, 1421, + 1425, 1417, 1414, 87, 1419, 1422, 87, 1420, 1426, 87, + 87, 1424, 87, 1429, 1427, 87, 1431, 1428, 1430, 87, + + 87, 87, 87, 87, 1432, 1433, 1434, 1436, 1437, 87, + 1435, 87, 87, 87, 87, 87, 1443, 1439, 87, 1441, + 87, 1438, 87, 1444, 87, 87, 87, 1445, 1440, 1447, + 87, 1448, 87, 1446, 87, 1442, 87, 1452, 1449, 1454, + 1455, 1456, 87, 87, 1450, 87, 87, 87, 1457, 1453, + 87, 1459, 1451, 87, 1461, 1458, 87, 87, 1460, 87, + 87, 1462, 1464, 1465, 87, 87, 1467, 87, 87, 87, + 1466, 87, 87, 1471, 87, 87, 87, 1463, 87, 1468, + 1469, 1470, 87, 87, 87, 1474, 1475, 1476, 87, 1477, + 87, 1481, 1472, 1482, 1473, 87, 1478, 87, 87, 87, + + 1479, 1485, 87, 1484, 87, 87, 1488, 87, 87, 1480, + 1483, 1491, 87, 87, 87, 87, 87, 87, 87, 1487, + 1489, 87, 1495, 1486, 87, 1490, 1493, 87, 1499, 87, + 87, 1492, 1500, 1494, 87, 1501, 1498, 175, 87, 1502, + 1497, 1496, 87, 87, 87, 87, 87, 1510, 87, 1507, + 87, 87, 1504, 1512, 1506, 1508, 1513, 1503, 1505, 87, + 1509, 87, 87, 87, 87, 87, 1515, 87, 87, 1514, + 1511, 87, 1517, 1518, 87, 87, 87, 87, 1520, 1516, + 1519, 1522, 1521, 87, 1524, 87, 1525, 87, 87, 1523, + 1529, 87, 1526, 87, 87, 87, 1528, 1532, 1531, 1534, + + 87, 87, 1527, 87, 87, 87, 87, 1530, 1542, 1536, + 170, 1538, 87, 1533, 87, 1535, 87, 1543, 87, 1544, + 1539, 1537, 1540, 1545, 87, 1541, 87, 87, 87, 87, + 1551, 1547, 1549, 1546, 87, 87, 87, 87, 1556, 87, + 1553, 1548, 87, 1552, 87, 87, 87, 1550, 87, 1555, + 1557, 1561, 87, 1558, 87, 1554, 87, 1559, 87, 1562, + 87, 1560, 87, 1563, 87, 1565, 1566, 87, 1564, 87, + 87, 1568, 87, 1567, 87, 1571, 87, 87, 87, 87, + 87, 1574, 1569, 87, 1572, 1573, 1579, 1583, 1570, 1575, + 87, 87, 87, 87, 87, 1576, 87, 1578, 1580, 1577, + + 87, 1581, 87, 87, 87, 1586, 87, 1587, 87, 87, + 1593, 1584, 1582, 87, 1585, 1589, 87, 87, 1595, 1588, + 87, 1590, 87, 1592, 87, 1600, 1594, 87, 1596, 1591, + 1598, 1597, 1601, 87, 87, 87, 1603, 87, 87, 1608, + 1599, 1604, 87, 87, 87, 1602, 1616, 87, 87, 1606, + 1607, 1622, 1619, 1605, 87, 1609, 1617, 1618, 87, 1610, + 87, 1620, 1611, 1612, 87, 87, 1624, 1613, 87, 1621, + 87, 87, 87, 1614, 1623, 1625, 1626, 1615, 87, 1627, + 87, 87, 1630, 87, 1629, 87, 1632, 87, 1633, 1628, + 1631, 87, 1637, 87, 1638, 87, 1639, 87, 87, 1636, + + 87, 1640, 87, 87, 87, 1634, 1641, 87, 1643, 1635, + 1646, 87, 168, 1648, 87, 87, 87, 1647, 1644, 87, + 1649, 87, 1642, 87, 87, 1645, 87, 1650, 1658, 87, + 1659, 1657, 87, 1652, 1651, 87, 1660, 1661, 1653, 87, + 1654, 87, 1655, 1662, 1656, 1663, 87, 87, 87, 87, + 1664, 1668, 87, 1669, 87, 1670, 87, 1667, 87, 87, + 1671, 87, 1672, 87, 87, 1666, 1665, 1674, 1675, 87, + 1673, 87, 87, 87, 1678, 1676, 87, 87, 1684, 87, + 1685, 1680, 87, 87, 87, 1679, 1677, 87, 87, 87, + 87, 1683, 1681, 87, 1686, 1682, 1687, 1688, 1689, 1691, + + 87, 1690, 87, 87, 1696, 87, 87, 1692, 1695, 1698, + 87, 87, 87, 87, 1694, 1700, 1699, 1702, 87, 87, + 1693, 1697, 1701, 87, 1705, 87, 87, 1707, 87, 87, + 1708, 87, 1704, 87, 87, 87, 1709, 1703, 1713, 87, + 87, 87, 87, 87, 1718, 1716, 1706, 87, 87, 87, + 87, 1721, 1719, 87, 1710, 1711, 1712, 1720, 1715, 87, + 1714, 87, 1723, 1717, 1724, 87, 87, 87, 87, 87, + 87, 1722, 1727, 87, 1729, 87, 87, 1799, 1730, 1726, + 1725, 1731, 1728, 87, 87, 87, 1732, 87, 1734, 1733, + 1735, 1736, 87, 87, 87, 1740, 1741, 87, 1737, 87, + + 1738, 87, 87, 87, 1742, 87, 87, 1739, 1745, 87, + 1743, 1744, 87, 87, 87, 87, 1747, 1754, 1746, 87, + 1749, 1750, 87, 1748, 87, 175, 87, 87, 1759, 1753, + 1760, 87, 87, 1751, 87, 1752, 87, 1761, 1763, 87, + 1756, 87, 87, 1762, 87, 1769, 1757, 1768, 87, 87, + 1758, 87, 87, 1764, 87, 1766, 87, 1774, 87, 1765, + 87, 1767, 87, 1772, 1771, 87, 87, 87, 1770, 87, + 1778, 87, 1773, 1780, 87, 87, 1782, 1786, 1775, 87, + 1777, 87, 1787, 87, 1779, 1776, 87, 87, 1783, 1784, + 1781, 87, 1785, 87, 87, 87, 1790, 87, 87, 1788, + + 87, 1791, 87, 1796, 1789, 1792, 1797, 87, 1804, 1793, + 1794, 1798, 1801, 1795, 1800, 87, 1805, 87, 87, 1803, + 87, 1806, 87, 1802, 87, 87, 87, 87, 87, 87, + 1810, 1811, 1812, 87, 87, 87, 1807, 87, 1815, 87, + 87, 1820, 1809, 87, 87, 1824, 1808, 1813, 1814, 1817, + 87, 87, 87, 87, 1816, 1818, 1821, 1819, 87, 87, + 87, 1822, 1825, 1823, 87, 87, 87, 87, 87, 1826, + 87, 1832, 166, 1828, 1833, 1829, 87, 1827, 87, 1830, + 87, 1834, 87, 1840, 1831, 1837, 1835, 87, 87, 87, + 87, 1838, 1836, 87, 1844, 1845, 1839, 87, 1842, 1846, + + 87, 87, 87, 1841, 87, 87, 87, 1848, 1849, 87, + 1843, 1847, 87, 87, 87, 1854, 1851, 1862, 1850, 1853, + 1855, 87, 1856, 1852, 87, 1857, 87, 87, 87, 87, + 1858, 1861, 87, 87, 87, 87, 1863, 87, 87, 87, + 87, 1869, 1872, 87, 1868, 1865, 87, 87, 87, 1859, + 1867, 1860, 1864, 1866, 1871, 87, 1876, 1874, 1870, 1878, + 1873, 1877, 87, 87, 1879, 87, 1875, 1880, 87, 87, + 1882, 87, 87, 87, 87, 1887, 87, 87, 87, 1886, + 1892, 87, 1885, 87, 87, 87, 87, 1894, 1881, 1893, + 1883, 1884, 87, 87, 87, 1888, 1889, 87, 1890, 87, + + 1900, 1891, 1898, 1895, 87, 87, 87, 1903, 87, 1897, + 87, 1902, 1896, 87, 87, 87, 87, 87, 87, 1905, + 87, 87, 87, 1901, 1914, 1899, 87, 1904, 87, 1913, + 87, 87, 1910, 1906, 1907, 1908, 1909, 1912, 1918, 87, + 87, 1911, 87, 1917, 1921, 1915, 1919, 87, 87, 1916, + 87, 87, 87, 1920, 87, 1922, 87, 1930, 1926, 87, + 1924, 87, 1927, 87, 1929, 1923, 87, 1925, 87, 1932, + 1933, 87, 87, 1934, 87, 1928, 87, 1931, 1938, 87, + 87, 1939, 1940, 87, 87, 1943, 1935, 87, 87, 1944, + 1937, 87, 1936, 87, 87, 1941, 1942, 1945, 1946, 87, + + 87, 87, 1951, 1952, 87, 87, 1954, 1947, 87, 1949, + 87, 87, 87, 87, 1957, 87, 1956, 1948, 1958, 1960, + 87, 1950, 87, 1953, 87, 1961, 1962, 87, 87, 87, + 87, 1955, 87, 87, 87, 1959, 1966, 87, 87, 87, + 1971, 87, 87, 87, 1963, 1964, 1965, 1969, 87, 87, + 87, 87, 1978, 1967, 1968, 1976, 1972, 1970, 87, 87, + 1979, 87, 1974, 1973, 1975, 1977, 1981, 87, 87, 87, + 1980, 87, 1985, 87, 87, 87, 87, 1990, 87, 87, + 1988, 87, 1982, 1991, 87, 1993, 87, 1986, 87, 1984, + 87, 1989, 1987, 1983, 87, 87, 87, 87, 87, 1998, + + 87, 1992, 2000, 2002, 87, 1997, 1994, 2003, 87, 1996, + 1995, 2005, 2004, 87, 87, 1999, 87, 175, 2001, 87, + 87, 2007, 87, 87, 87, 2014, 87, 2006, 87, 2016, + 87, 2017, 2015, 2008, 2010, 87, 87, 2009, 2013, 87, + 2019, 2011, 2012, 87, 2023, 87, 2021, 87, 87, 87, + 2018, 87, 2025, 2027, 87, 2029, 2020, 2024, 2022, 2028, + 87, 87, 2031, 87, 87, 87, 2034, 87, 87, 2026, + 2032, 87, 87, 87, 87, 87, 87, 2033, 2037, 2039, + 2030, 2038, 87, 2035, 87, 2042, 87, 2040, 87, 2043, + 2036, 87, 87, 87, 2045, 2047, 2041, 87, 2048, 87, + + 2044, 87, 87, 87, 2056, 2052, 2046, 87, 2053, 87, + 87, 2049, 2057, 2050, 87, 2055, 87, 2058, 2060, 2051, + 2054, 2061, 87, 87, 2064, 87, 2063, 87, 2066, 2067, + 87, 87, 87, 2059, 87, 87, 2068, 87, 2069, 87, + 2070, 87, 2071, 2073, 87, 87, 2072, 2062, 87, 87, + 2074, 2065, 2077, 2078, 2079, 2080, 87, 87, 2082, 87, + 87, 87, 2081, 2075, 87, 2076, 87, 2085, 87, 87, + 87, 2084, 87, 87, 2086, 87, 87, 87, 87, 2083, + 87, 87, 87, 87, 87, 87, 87, 2098, 2087, 87, + 2089, 2090, 2088, 2101, 2093, 2091, 2094, 2092, 2095, 2096, + + 87, 2102, 2099, 2097, 2100, 87, 87, 2105, 87, 87, + 87, 87, 87, 87, 2110, 87, 2112, 2103, 87, 2104, + 2114, 87, 87, 87, 87, 2107, 2109, 2113, 2106, 2116, + 2108, 87, 2111, 87, 2118, 2117, 87, 87, 87, 87, + 87, 87, 2115, 87, 2124, 87, 2119, 2129, 2123, 87, + 2120, 87, 87, 87, 87, 2125, 2122, 2126, 2128, 2127, + 2130, 2121, 2218, 2131, 87, 2132, 87, 2133, 87, 2137, + 2136, 2135, 2134, 2138, 87, 2139, 87, 87, 87, 87, + 2140, 2143, 2141, 2145, 87, 87, 2142, 87, 87, 87, + 87, 87, 2151, 2148, 2144, 87, 2150, 87, 2146, 87, + + 87, 87, 87, 87, 2154, 87, 2147, 2149, 87, 87, + 4206, 2157, 2164, 87, 87, 2153, 2152, 2156, 2159, 2155, + 2163, 2160, 2158, 2162, 87, 87, 87, 87, 2166, 2161, + 87, 2165, 87, 87, 2171, 87, 87, 87, 2167, 2172, + 87, 2173, 87, 2177, 2169, 2168, 87, 2174, 2170, 2178, + 87, 87, 87, 2181, 4206, 2176, 87, 2182, 2175, 87, + 2180, 87, 2183, 87, 87, 2185, 2179, 2188, 2186, 87, + 87, 2190, 87, 2187, 2189, 2191, 2184, 87, 87, 2195, + 87, 2192, 87, 87, 2196, 87, 87, 87, 87, 2202, + 87, 2200, 2204, 87, 2197, 87, 2194, 2198, 2193, 87, + + 87, 2201, 2205, 2208, 2206, 2199, 2203, 87, 87, 87, + 2210, 87, 87, 2209, 2207, 2213, 87, 2217, 87, 87, + 87, 87, 2215, 87, 87, 87, 2212, 87, 2216, 2214, + 87, 2211, 2223, 2222, 87, 87, 87, 2219, 87, 2220, + 87, 87, 2232, 2221, 2224, 2226, 2233, 2225, 2230, 87, + 2234, 2227, 87, 87, 2228, 2229, 87, 87, 2237, 87, + 2235, 87, 87, 87, 2241, 87, 2236, 2243, 87, 87, + 2231, 87, 4206, 87, 87, 2247, 87, 87, 87, 87, + 2239, 2238, 2240, 2249, 2242, 2245, 87, 87, 87, 87, + 2244, 2251, 2246, 2253, 2254, 87, 87, 2248, 2250, 87, + + 87, 87, 87, 2258, 2255, 175, 87, 2252, 2257, 2262, + 87, 2261, 2260, 87, 2259, 2265, 87, 2263, 87, 2256, + 87, 2269, 87, 87, 87, 2264, 87, 87, 2270, 87, + 2267, 87, 2266, 2272, 2274, 87, 87, 87, 2271, 2268, + 87, 2273, 2280, 2275, 87, 87, 2276, 87, 87, 87, + 2285, 2283, 2284, 87, 87, 87, 2277, 2279, 87, 2278, + 2288, 2281, 2282, 2287, 87, 2289, 87, 87, 2294, 87, + 2293, 87, 87, 2290, 2286, 2291, 87, 87, 87, 2296, + 87, 2297, 87, 2292, 2295, 87, 87, 87, 87, 87, + 87, 2302, 87, 2303, 87, 87, 87, 87, 2304, 2307, + + 2298, 2308, 2305, 2300, 2299, 2301, 2309, 2306, 87, 87, + 87, 2316, 87, 2312, 2314, 2311, 2317, 87, 87, 2310, + 2313, 87, 87, 87, 87, 2315, 87, 87, 2324, 87, + 2327, 87, 2328, 87, 2319, 2329, 87, 87, 2318, 87, + 2320, 87, 2321, 2322, 2323, 2325, 87, 2326, 2331, 87, + 87, 2332, 2336, 87, 87, 2338, 87, 2330, 2337, 2339, + 2333, 87, 2334, 2340, 87, 2342, 87, 2335, 87, 87, + 87, 87, 87, 87, 87, 2345, 2347, 2344, 2348, 87, + 87, 87, 2341, 2351, 87, 2350, 87, 87, 87, 2343, + 87, 2356, 2354, 2355, 2349, 87, 2352, 2346, 2358, 87, + + 2357, 87, 87, 87, 87, 87, 87, 2353, 2366, 87, + 87, 2359, 2360, 2361, 87, 2370, 2369, 87, 2362, 87, + 2364, 2363, 2371, 2365, 87, 2367, 2368, 2372, 87, 87, + 87, 2373, 2375, 2378, 2374, 2376, 87, 87, 87, 87, + 87, 87, 87, 87, 2377, 2379, 2386, 87, 87, 87, + 2388, 87, 2381, 87, 87, 2391, 87, 2380, 87, 2382, + 2383, 2384, 2385, 2392, 87, 2393, 87, 2395, 87, 87, + 87, 2389, 87, 2397, 2387, 2390, 2394, 2399, 87, 2398, + 87, 2400, 2402, 2396, 87, 87, 87, 2407, 87, 87, + 2408, 87, 87, 87, 87, 87, 87, 2414, 87, 87, + + 87, 2401, 2405, 2406, 2404, 2403, 2411, 2412, 87, 2410, + 2415, 87, 2418, 2409, 87, 87, 2420, 2423, 87, 2419, + 87, 2413, 87, 87, 2417, 87, 2416, 2422, 87, 87, + 2424, 2426, 2427, 87, 2428, 2421, 87, 87, 87, 87, + 87, 87, 87, 2433, 2425, 2429, 87, 87, 87, 2435, + 87, 2438, 87, 2430, 2434, 87, 2439, 2441, 87, 2431, + 2432, 87, 2443, 87, 87, 2436, 2444, 87, 87, 87, + 2442, 87, 87, 2447, 2437, 2440, 87, 2452, 87, 87, + 87, 2451, 2446, 87, 2445, 87, 87, 87, 2449, 2448, + 2457, 87, 2458, 2450, 87, 87, 2460, 87, 2455, 2454, + + 2459, 2461, 87, 2453, 2456, 87, 2462, 87, 87, 2463, + 2466, 87, 87, 87, 87, 87, 2467, 87, 2464, 2470, + 2474, 87, 2468, 2465, 87, 87, 87, 87, 87, 2477, + 87, 2469, 87, 2471, 2481, 2472, 2482, 2473, 87, 2475, + 2476, 2478, 2479, 87, 87, 2480, 87, 87, 87, 2484, + 87, 2483, 2487, 2519, 2485, 2488, 87, 2489, 87, 2490, + 87, 2492, 2493, 2497, 2491, 87, 2486, 87, 87, 87, + 87, 87, 2496, 87, 2494, 2495, 87, 2499, 87, 87, + 2502, 2500, 87, 2498, 87, 2504, 2506, 87, 87, 87, + 2501, 87, 87, 87, 2509, 2510, 87, 87, 87, 175, + + 87, 87, 2507, 2508, 2513, 2524, 2505, 2503, 87, 87, + 2514, 87, 2511, 2515, 2517, 2518, 87, 2512, 87, 2516, + 87, 2520, 2521, 87, 87, 2522, 2523, 87, 2526, 2527, + 87, 87, 87, 2525, 87, 87, 2528, 2529, 87, 87, + 2530, 87, 87, 2533, 2532, 2535, 87, 2531, 2534, 87, + 2536, 87, 2537, 2538, 87, 2540, 87, 87, 87, 2544, + 87, 87, 87, 2543, 2549, 87, 2539, 2546, 2541, 2542, + 2545, 87, 87, 87, 87, 2548, 2547, 87, 87, 2554, + 87, 87, 2557, 2551, 2555, 87, 2556, 87, 87, 87, + 87, 87, 87, 2550, 87, 2552, 87, 2553, 2559, 87, + + 2562, 87, 87, 2565, 87, 2558, 2561, 87, 2560, 2564, + 2566, 2563, 87, 2568, 87, 87, 2567, 87, 2576, 2570, + 2572, 2574, 87, 2569, 87, 2571, 87, 2575, 87, 87, + 2573, 87, 2581, 87, 87, 2583, 4206, 87, 87, 2584, + 87, 87, 2577, 2580, 2578, 87, 2579, 2586, 2588, 87, + 2582, 87, 2590, 87, 2585, 87, 2591, 87, 87, 2589, + 2594, 87, 87, 2587, 2593, 87, 87, 87, 87, 2596, + 87, 2599, 87, 2600, 87, 2595, 87, 87, 87, 2603, + 2592, 2601, 87, 87, 87, 87, 87, 2597, 2598, 2604, + 2606, 2605, 2608, 87, 87, 2602, 2610, 2620, 87, 2609, + + 87, 2611, 87, 87, 87, 2617, 2613, 2614, 2607, 2612, + 2615, 87, 2619, 87, 2622, 87, 2618, 87, 2623, 87, + 2625, 2621, 2624, 2616, 2626, 87, 2627, 87, 87, 87, + 87, 2631, 2628, 2630, 87, 87, 87, 87, 87, 2633, + 2637, 87, 2634, 87, 87, 2635, 2640, 2629, 2632, 87, + 2639, 87, 2638, 87, 2644, 2636, 87, 87, 87, 2648, + 87, 87, 2650, 87, 87, 87, 2642, 87, 2641, 2653, + 2652, 87, 87, 2643, 87, 2649, 2645, 2646, 2647, 2654, + 87, 87, 2659, 87, 87, 2655, 87, 4206, 87, 2656, + 2651, 2660, 2658, 87, 87, 2663, 2661, 87, 87, 2657, + + 2664, 87, 2665, 2666, 87, 2662, 2669, 87, 87, 2670, + 2668, 2667, 87, 87, 2674, 2671, 87, 87, 2677, 2676, + 87, 2675, 2678, 87, 87, 2680, 2681, 2672, 87, 87, + 87, 87, 87, 2673, 2684, 87, 87, 2682, 87, 2686, + 87, 2679, 2685, 87, 2687, 2683, 87, 87, 87, 2688, + 87, 2689, 2691, 87, 2690, 2694, 2692, 2696, 87, 2693, + 87, 87, 2697, 87, 87, 87, 87, 87, 87, 2699, + 2698, 2695, 2703, 2700, 87, 87, 87, 2701, 2702, 2704, + 87, 2705, 87, 2706, 87, 2708, 2709, 87, 87, 87, + 2714, 87, 87, 87, 87, 2707, 87, 2717, 2710, 87, + + 2711, 87, 2712, 2715, 2713, 2718, 2716, 87, 2719, 2721, + 87, 87, 2722, 87, 2720, 87, 2723, 2725, 87, 87, + 87, 2726, 2724, 87, 2728, 87, 2732, 87, 2734, 87, + 87, 2737, 87, 87, 2727, 2730, 2733, 87, 2736, 2735, + 87, 2731, 2729, 87, 2740, 87, 87, 87, 2741, 87, + 175, 2738, 87, 2747, 87, 87, 2739, 2751, 2742, 87, + 2743, 2749, 2744, 87, 2752, 87, 2750, 87, 2753, 2745, + 87, 2746, 2748, 87, 2755, 2756, 87, 87, 2759, 87, + 87, 2754, 87, 2760, 2764, 87, 87, 2765, 87, 2763, + 87, 87, 2769, 87, 87, 2758, 2768, 2761, 87, 2757, + + 2766, 87, 87, 87, 2774, 2775, 87, 2772, 2762, 2767, + 87, 2777, 2773, 2771, 87, 2776, 2770, 87, 2778, 87, + 87, 87, 87, 87, 2780, 87, 87, 87, 2783, 87, + 87, 87, 87, 87, 2787, 87, 2793, 87, 2791, 2779, + 87, 2781, 2785, 87, 2786, 87, 2789, 2782, 2784, 2788, + 87, 87, 2790, 87, 2794, 2795, 2796, 2792, 87, 87, + 87, 2797, 87, 87, 87, 2800, 87, 2802, 2805, 87, + 87, 2798, 2806, 2803, 87, 87, 2799, 87, 2801, 87, + 87, 2804, 87, 87, 2816, 2807, 87, 87, 4206, 2808, + 87, 2818, 87, 2809, 2814, 2817, 87, 87, 2810, 2812, + + 2813, 2811, 2819, 87, 2815, 2820, 87, 87, 2823, 2822, + 2821, 2825, 87, 87, 87, 87, 87, 2827, 2826, 87, + 87, 87, 87, 2832, 2833, 87, 87, 2824, 2828, 87, + 87, 2834, 2853, 2830, 2831, 2835, 87, 87, 87, 2839, + 2829, 2836, 2840, 2841, 87, 2837, 87, 2842, 87, 87, + 2838, 87, 2844, 2847, 87, 2848, 87, 87, 2845, 87, + 87, 2846, 2849, 2843, 2850, 87, 87, 87, 87, 2857, + 87, 2858, 87, 87, 2860, 87, 2856, 87, 87, 2854, + 2851, 2855, 2862, 87, 87, 2852, 2865, 87, 87, 2864, + 2866, 87, 2859, 2863, 87, 2861, 87, 87, 2870, 87, + + 87, 87, 2867, 2868, 2872, 87, 87, 87, 2873, 87, + 2874, 2878, 87, 87, 2877, 87, 2869, 2871, 2880, 87, + 2875, 87, 87, 87, 2884, 87, 2876, 2882, 87, 2883, + 87, 2885, 2879, 2881, 2887, 87, 87, 87, 2890, 87, + 2893, 87, 2894, 2889, 2888, 87, 2886, 87, 87, 87, + 87, 87, 2891, 87, 2899, 2900, 87, 87, 2892, 87, + 87, 87, 2896, 87, 2905, 2895, 2898, 87, 2904, 87, + 2911, 87, 2897, 2902, 2906, 87, 2901, 2913, 87, 2903, + 87, 2914, 2910, 2907, 2912, 87, 87, 2915, 87, 2916, + 2908, 2909, 87, 87, 2921, 87, 87, 2923, 87, 87, + + 2927, 2924, 87, 2917, 2918, 2922, 87, 2919, 87, 87, + 87, 2928, 87, 2929, 2920, 2930, 2925, 2931, 2926, 87, + 87, 87, 2933, 87, 87, 87, 2936, 2932, 87, 2935, + 2938, 87, 2942, 2939, 87, 2943, 2940, 87, 87, 2941, + 2934, 87, 2946, 87, 87, 87, 87, 87, 87, 2937, + 2947, 2948, 2945, 87, 87, 2944, 2951, 2950, 87, 2958, + 87, 87, 87, 2953, 87, 87, 87, 2952, 2949, 2954, + 2955, 2956, 2957, 2959, 87, 87, 87, 2966, 2960, 87, + 87, 2965, 2962, 87, 2961, 2964, 2969, 87, 2967, 87, + 87, 87, 87, 2971, 87, 2963, 2968, 87, 2973, 2972, + + 2970, 175, 87, 87, 2979, 87, 2974, 87, 87, 87, + 87, 87, 87, 87, 2975, 2984, 2976, 2981, 2977, 2978, + 2982, 2983, 2980, 87, 2985, 2986, 87, 87, 87, 2989, + 87, 87, 87, 2990, 2994, 87, 2995, 87, 2987, 2988, + 2992, 2996, 87, 87, 2993, 87, 2998, 2999, 87, 87, + 2991, 87, 3000, 3002, 3003, 87, 3001, 3005, 87, 87, + 87, 87, 87, 2997, 3004, 87, 3007, 87, 3009, 87, + 87, 87, 3012, 3013, 3008, 3006, 87, 87, 87, 87, + 87, 3017, 3015, 3010, 3016, 3018, 87, 87, 87, 3011, + 3014, 87, 3019, 3020, 87, 87, 87, 87, 3025, 87, + + 3021, 3024, 87, 3022, 87, 87, 87, 3027, 87, 3026, + 87, 87, 87, 3035, 3032, 3023, 87, 3034, 87, 87, + 87, 87, 3031, 3038, 3028, 3029, 3030, 3036, 87, 3037, + 87, 3033, 87, 3039, 3040, 87, 87, 3045, 87, 3041, + 3043, 87, 87, 87, 3049, 3050, 87, 87, 3048, 3042, + 87, 87, 87, 3046, 3051, 87, 3053, 3044, 3047, 87, + 87, 3052, 87, 3056, 87, 87, 3054, 3057, 3059, 3055, + 87, 3058, 87, 87, 3065, 3060, 3061, 87, 3063, 87, + 87, 87, 87, 3064, 3067, 87, 87, 87, 87, 87, + 87, 3068, 3069, 3066, 87, 3070, 3071, 87, 3062, 3072, + + 87, 87, 3076, 87, 3074, 87, 3073, 87, 3078, 87, + 3075, 87, 87, 87, 3085, 87, 3087, 3083, 3084, 3086, + 87, 3079, 87, 87, 3082, 87, 3080, 3077, 87, 3089, + 87, 87, 87, 87, 87, 3081, 3092, 3094, 87, 3097, + 87, 3090, 87, 3088, 87, 3095, 87, 87, 87, 3101, + 3096, 3093, 3091, 3099, 3100, 87, 3104, 87, 3098, 87, + 87, 87, 3103, 87, 3102, 87, 3107, 3108, 3105, 3106, + 87, 87, 87, 87, 87, 87, 3109, 3111, 87, 87, + 3112, 87, 3117, 3118, 87, 3110, 87, 87, 3122, 87, + 87, 3119, 3113, 3114, 3115, 3123, 3116, 3120, 3121, 87, + + 87, 3124, 87, 87, 87, 87, 87, 3129, 87, 3128, + 4206, 3131, 3132, 87, 3125, 3127, 3126, 3134, 87, 3135, + 87, 3136, 87, 3133, 87, 3130, 87, 87, 3138, 87, + 87, 3141, 87, 3142, 3140, 87, 3137, 87, 3143, 87, + 87, 87, 87, 87, 87, 3139, 87, 3144, 3150, 87, + 3152, 87, 3146, 3153, 87, 3155, 87, 3154, 87, 3145, + 3149, 3147, 3151, 3148, 87, 87, 87, 87, 87, 87, + 3156, 3157, 3160, 3163, 87, 87, 87, 3158, 3166, 87, + 87, 87, 87, 87, 3164, 87, 3159, 87, 3161, 3162, + 87, 3172, 87, 87, 87, 3169, 3165, 87, 87, 3171, + + 3176, 3168, 3173, 175, 3174, 87, 3167, 3170, 87, 3175, + 87, 3178, 3180, 87, 3179, 3177, 3183, 87, 87, 87, + 3186, 87, 87, 3181, 3185, 3188, 87, 87, 87, 3192, + 87, 3182, 3190, 3191, 3193, 87, 87, 87, 3195, 3184, + 3189, 3187, 87, 87, 3197, 87, 3198, 87, 3194, 87, + 87, 3196, 87, 87, 87, 87, 87, 87, 87, 87, + 3200, 87, 87, 3210, 4206, 3199, 3208, 3202, 87, 3201, + 87, 87, 3204, 3203, 87, 3214, 3206, 3205, 3207, 3209, + 87, 87, 3211, 87, 3215, 3217, 3212, 87, 3213, 3216, + 87, 87, 3219, 3220, 87, 87, 3221, 3222, 87, 87, + + 87, 87, 87, 3218, 87, 87, 87, 3226, 87, 3223, + 87, 87, 3232, 3224, 3233, 87, 3227, 3225, 3234, 87, + 3228, 3230, 3229, 3235, 87, 3231, 3236, 87, 87, 3240, + 87, 3241, 87, 3242, 3239, 3237, 87, 3238, 87, 87, + 87, 87, 87, 87, 3249, 87, 87, 3248, 87, 87, + 87, 87, 87, 87, 3243, 3245, 3244, 3247, 3256, 87, + 3246, 3253, 3254, 87, 87, 3257, 3250, 87, 3251, 3252, + 3258, 87, 3255, 87, 87, 3259, 3260, 87, 3261, 3262, + 87, 3264, 87, 3263, 87, 87, 3266, 87, 3270, 87, + 87, 87, 3269, 3265, 3268, 87, 3272, 3267, 87, 87, + + 3273, 87, 87, 3274, 87, 87, 87, 3279, 3280, 87, + 3271, 87, 3283, 87, 87, 87, 87, 87, 4206, 3275, + 3276, 3281, 3277, 3278, 87, 3284, 87, 87, 3286, 3282, + 3285, 3287, 3288, 3289, 87, 3291, 87, 87, 3290, 3292, + 87, 87, 3296, 87, 87, 87, 87, 87, 87, 87, + 3293, 87, 3299, 3294, 87, 87, 3295, 3297, 3298, 87, + 3301, 4206, 3304, 87, 3300, 3306, 87, 3307, 3302, 3305, + 3303, 87, 3308, 87, 3310, 3309, 3311, 87, 3312, 3313, + 87, 87, 87, 87, 87, 87, 3314, 3319, 87, 87, + 87, 3315, 87, 3321, 87, 87, 3317, 3324, 87, 3316, + + 87, 87, 87, 3322, 87, 3318, 87, 87, 3325, 4206, + 3320, 3328, 3323, 3326, 3327, 3329, 3330, 3331, 87, 87, + 3334, 87, 87, 87, 3332, 87, 87, 3335, 3336, 87, + 87, 3338, 87, 87, 3333, 87, 87, 3339, 87, 3337, + 87, 3341, 87, 3342, 87, 3345, 87, 3346, 3343, 3340, + 3348, 87, 87, 3347, 87, 3344, 3349, 87, 87, 3351, + 87, 3352, 87, 3353, 3350, 3355, 175, 3356, 87, 87, + 3360, 3354, 87, 3357, 87, 87, 87, 3361, 87, 3362, + 3358, 87, 3364, 87, 3367, 87, 87, 3359, 3366, 3363, + 3368, 87, 87, 3365, 87, 3372, 87, 3369, 87, 3370, + + 3374, 3373, 87, 87, 87, 3375, 87, 3376, 3371, 3377, + 3379, 87, 87, 87, 87, 3380, 87, 3378, 3381, 3382, + 87, 3383, 87, 87, 87, 3387, 3388, 87, 87, 3389, + 3385, 87, 87, 3391, 87, 3384, 87, 87, 87, 3390, + 3395, 3394, 3393, 3392, 3386, 87, 87, 87, 87, 87, + 3396, 3397, 3398, 3406, 87, 87, 87, 3403, 87, 87, + 87, 87, 3400, 3401, 3402, 3405, 3399, 3404, 87, 3409, + 87, 87, 87, 3407, 87, 87, 3410, 87, 3408, 3415, + 87, 87, 87, 4206, 87, 87, 87, 87, 3416, 87, + 3411, 87, 3412, 3418, 3413, 3419, 3414, 87, 3420, 87, + + 3421, 3417, 3423, 3424, 87, 87, 3430, 87, 3422, 3427, + 3425, 87, 87, 87, 3428, 3432, 3429, 3433, 87, 87, + 3426, 87, 87, 87, 3436, 87, 3437, 87, 3438, 3439, + 87, 87, 87, 87, 87, 87, 87, 3434, 3431, 3440, + 3435, 3442, 3443, 3445, 3441, 3444, 87, 87, 87, 87, + 3446, 87, 3447, 3448, 3450, 87, 87, 3452, 87, 87, + 3449, 87, 87, 3453, 3454, 87, 3451, 87, 87, 3461, + 87, 87, 87, 4206, 3458, 3456, 3460, 3463, 87, 3455, + 87, 3457, 3464, 87, 3465, 87, 87, 87, 87, 3468, + 3459, 3466, 87, 3467, 87, 3462, 3469, 87, 87, 3471, + + 87, 87, 3473, 87, 3472, 4206, 3470, 3474, 87, 87, + 3475, 87, 3479, 3480, 87, 3481, 87, 3482, 87, 87, + 3476, 3477, 3483, 3478, 87, 87, 3486, 87, 87, 3488, + 3489, 87, 87, 3490, 3491, 87, 87, 3484, 3485, 3493, + 87, 87, 87, 87, 3497, 87, 3487, 3498, 3499, 87, + 87, 3492, 87, 87, 3494, 3505, 3500, 3496, 3502, 87, + 3495, 87, 3504, 3503, 87, 87, 87, 3507, 87, 87, + 3501, 3506, 3508, 87, 87, 87, 3513, 3514, 3515, 3518, + 87, 3512, 87, 87, 87, 87, 87, 4206, 3509, 3510, + 3517, 3519, 87, 3516, 3511, 87, 87, 87, 87, 87, + + 3520, 3523, 3525, 3521, 87, 3522, 87, 3526, 87, 87, + 3524, 3531, 87, 3529, 87, 87, 3534, 87, 87, 87, + 87, 3527, 3528, 3536, 87, 3546, 87, 3530, 87, 3533, + 87, 3537, 3535, 3538, 3532, 3541, 3540, 87, 3547, 3543, + 3542, 87, 87, 3539, 3544, 87, 87, 3548, 87, 3545, + 87, 3549, 87, 3550, 87, 3551, 87, 87, 3552, 87, + 87, 3553, 87, 87, 87, 87, 3557, 87, 3554, 3556, + 3559, 87, 3561, 3562, 87, 87, 3558, 3566, 87, 3567, + 87, 87, 3560, 3555, 3568, 87, 3570, 87, 87, 87, + 87, 3563, 87, 3572, 3564, 3565, 3571, 3574, 87, 3575, + + 3569, 3576, 87, 87, 87, 3579, 87, 3573, 87, 3578, + 87, 3582, 87, 87, 87, 87, 87, 3580, 87, 3581, + 3586, 87, 3583, 3584, 3577, 3587, 87, 87, 87, 3591, + 87, 3588, 87, 3585, 3594, 3590, 87, 3589, 87, 3595, + 87, 87, 87, 87, 87, 3592, 3603, 3597, 3600, 3596, + 87, 3601, 3593, 87, 87, 87, 3598, 3599, 3602, 3604, + 87, 87, 3608, 87, 87, 87, 3607, 3610, 87, 87, + 3605, 87, 3614, 87, 87, 3606, 3615, 87, 3609, 3611, + 3617, 87, 87, 3616, 87, 87, 87, 87, 87, 3613, + 3620, 3623, 87, 3618, 3612, 87, 3621, 87, 87, 3660, + + 3624, 87, 87, 3626, 3622, 87, 3627, 3619, 87, 3628, + 3630, 3629, 87, 3625, 87, 87, 87, 3631, 87, 87, + 3636, 3638, 87, 3637, 3639, 87, 3633, 87, 3632, 3634, + 3640, 87, 3635, 87, 87, 87, 3641, 87, 87, 3647, + 3646, 3648, 87, 87, 87, 87, 3651, 87, 3649, 3650, + 87, 87, 87, 3642, 3643, 87, 3644, 3645, 87, 3657, + 3655, 87, 87, 3653, 87, 87, 3659, 87, 3652, 3661, + 87, 87, 3663, 3654, 87, 3662, 3656, 87, 87, 3668, + 87, 3664, 87, 87, 87, 87, 3658, 87, 87, 3665, + 87, 3672, 3666, 87, 3673, 3669, 3670, 3671, 3667, 87, + + 87, 3676, 87, 87, 3674, 3677, 87, 3681, 87, 3675, + 87, 87, 3685, 87, 3679, 3686, 87, 3682, 87, 3678, + 87, 3688, 87, 3680, 87, 87, 3689, 87, 3683, 87, + 3691, 87, 3690, 3692, 87, 3693, 87, 3684, 87, 3687, + 3695, 3696, 87, 3694, 87, 3697, 87, 3698, 87, 3699, + 87, 3701, 3702, 87, 3700, 3705, 87, 3707, 87, 3704, + 87, 87, 87, 87, 3709, 87, 87, 87, 3703, 87, + 87, 87, 87, 87, 3710, 3715, 87, 3716, 87, 3706, + 87, 3708, 3720, 87, 3714, 3717, 3711, 3712, 3713, 3721, + 3723, 3719, 3718, 87, 87, 87, 87, 87, 3722, 3724, + + 3727, 87, 3725, 3728, 87, 87, 3731, 87, 87, 87, + 87, 87, 3729, 87, 87, 3736, 87, 3734, 87, 3726, + 3733, 87, 87, 3738, 3908, 3730, 3732, 3740, 87, 3741, + 3735, 87, 3737, 3744, 3739, 87, 3742, 3743, 87, 87, + 87, 87, 3745, 3746, 87, 3747, 87, 3748, 87, 3752, + 3753, 87, 3755, 3751, 87, 87, 87, 3754, 87, 87, + 87, 3749, 3758, 87, 3757, 3759, 3750, 87, 87, 3761, + 87, 3764, 87, 87, 3756, 87, 87, 87, 3769, 87, + 3765, 87, 87, 87, 3773, 87, 3760, 3762, 3763, 87, + 3768, 3766, 3772, 3774, 87, 3775, 87, 87, 3771, 87, + + 3770, 3767, 3776, 3777, 3778, 3779, 87, 3780, 87, 3781, + 87, 87, 87, 3784, 87, 87, 87, 3787, 87, 87, + 3782, 3789, 87, 87, 3788, 3791, 87, 87, 3785, 3792, + 87, 87, 87, 3783, 3790, 87, 87, 87, 87, 3799, + 3800, 87, 3786, 87, 87, 87, 3793, 87, 87, 87, + 3806, 87, 3794, 87, 3795, 3797, 87, 3796, 3805, 3798, + 3810, 3803, 87, 3802, 87, 3804, 3809, 87, 3807, 3801, + 87, 3813, 87, 3808, 87, 87, 3812, 87, 3815, 3817, + 87, 87, 3811, 87, 87, 87, 3820, 87, 3821, 4206, + 3814, 87, 3818, 3816, 3823, 87, 3824, 87, 87, 3819, + + 3827, 3826, 87, 3825, 87, 3822, 87, 3830, 87, 87, + 87, 3833, 3829, 87, 3828, 3831, 87, 3834, 87, 87, + 87, 3835, 87, 87, 87, 3832, 87, 3838, 87, 87, + 87, 87, 3839, 87, 3842, 3840, 87, 3843, 3836, 3837, + 87, 87, 3841, 87, 87, 3844, 87, 87, 3852, 3848, + 3845, 3846, 3853, 3855, 3847, 87, 87, 3849, 3850, 87, + 3856, 87, 3851, 87, 3854, 87, 3857, 3862, 3858, 3859, + 3860, 87, 3861, 87, 87, 87, 3863, 3865, 87, 3864, + 3866, 87, 3868, 87, 87, 3870, 87, 87, 3872, 3873, + 87, 87, 3874, 3875, 3879, 87, 3876, 87, 87, 3869, + + 3867, 3877, 3878, 3880, 87, 87, 3871, 3882, 87, 87, + 87, 3885, 87, 3887, 3881, 3886, 87, 3888, 87, 87, + 3889, 87, 87, 87, 3884, 87, 87, 3883, 87, 3890, + 3892, 87, 3893, 87, 87, 3894, 87, 3891, 3895, 3898, + 87, 3897, 3896, 3899, 87, 87, 87, 87, 3900, 87, + 3903, 4206, 3902, 87, 87, 87, 3904, 3910, 87, 87, + 3909, 87, 3912, 87, 3905, 3913, 87, 87, 3911, 3901, + 87, 3906, 3914, 87, 3907, 3915, 87, 87, 87, 87, + 87, 87, 3917, 3918, 3923, 3916, 3919, 3921, 4206, 3920, + 87, 87, 3922, 87, 3925, 3924, 3927, 87, 3930, 87, + + 3929, 3926, 3928, 3931, 87, 3933, 87, 3934, 87, 87, + 3932, 87, 87, 3937, 87, 87, 87, 3936, 3939, 87, + 3940, 87, 87, 3943, 87, 3941, 3935, 3944, 87, 3938, + 3945, 87, 3946, 87, 3947, 87, 3948, 87, 3949, 87, + 3942, 3950, 87, 3951, 87, 87, 87, 3954, 87, 87, + 87, 87, 87, 87, 3959, 3953, 3957, 3961, 87, 87, + 87, 87, 87, 87, 3966, 87, 3958, 87, 3960, 3955, + 3956, 3952, 3962, 3963, 87, 3965, 3968, 87, 87, 3964, + 87, 3967, 3969, 87, 3972, 87, 87, 3970, 3975, 87, + 3971, 3977, 87, 87, 87, 87, 87, 3974, 3978, 3973, + + 87, 3976, 3985, 3980, 87, 3982, 87, 87, 87, 3984, + 87, 87, 3979, 87, 3983, 87, 3987, 87, 87, 87, + 87, 3981, 87, 3995, 3986, 3991, 3988, 3992, 87, 87, + 3994, 3989, 3993, 3990, 87, 87, 87, 87, 3999, 3998, + 87, 87, 4002, 87, 87, 4000, 3996, 87, 87, 3997, + 4001, 4008, 87, 4009, 87, 87, 4003, 4007, 4010, 87, + 4011, 87, 4004, 4005, 4013, 4006, 87, 87, 4016, 87, + 4014, 4012, 87, 87, 4019, 87, 87, 87, 87, 4023, + 87, 4022, 87, 87, 4025, 87, 4018, 4015, 4017, 4021, + 87, 87, 87, 87, 87, 87, 87, 4024, 4020, 87, + + 87, 87, 87, 4026, 4027, 4032, 4033, 4034, 4029, 4028, + 4031, 87, 4036, 87, 4039, 87, 4037, 87, 4030, 87, + 4035, 4040, 87, 4043, 87, 87, 87, 87, 87, 87, + 4041, 87, 4038, 4048, 4046, 4042, 4051, 87, 87, 4044, + 87, 4053, 87, 4049, 4045, 4054, 87, 4047, 87, 4052, + 87, 4050, 87, 4055, 87, 4056, 4057, 87, 4058, 87, + 87, 4059, 87, 4061, 87, 87, 4066, 4062, 87, 4063, + 4060, 87, 87, 87, 4070, 87, 87, 4064, 4069, 87, + 4065, 4206, 4067, 4068, 4072, 87, 4073, 87, 4074, 87, + 4075, 87, 87, 87, 4078, 87, 4071, 4076, 4077, 4080, + + 87, 87, 4079, 4081, 87, 87, 4084, 87, 87, 87, + 87, 87, 4089, 87, 87, 4090, 4082, 87, 87, 87, + 4086, 4093, 4094, 4085, 4083, 4091, 87, 87, 87, 4088, + 87, 87, 87, 4095, 4087, 87, 4098, 4092, 87, 4096, + 4099, 87, 4100, 87, 87, 87, 87, 4101, 87, 4097, + 4102, 4107, 87, 4103, 87, 87, 87, 87, 4109, 4106, + 87, 4111, 87, 87, 4108, 4104, 4105, 87, 4116, 87, + 4118, 87, 87, 4113, 4117, 4110, 4112, 87, 87, 87, + 4114, 4115, 87, 87, 87, 87, 4126, 87, 87, 4127, + 87, 4128, 87, 4119, 4125, 4130, 4121, 87, 4120, 4122, + + 4123, 87, 4124, 87, 4129, 87, 4131, 4133, 4134, 87, + 4132, 87, 4135, 87, 87, 4137, 4138, 87, 4139, 4140, + 87, 87, 87, 87, 87, 87, 4142, 87, 4147, 4136, + 87, 4144, 87, 4206, 87, 4150, 87, 4151, 87, 4141, + 4152, 87, 4143, 87, 4145, 4149, 4146, 87, 4153, 4148, + 87, 4155, 87, 87, 87, 4154, 87, 87, 87, 4158, + 87, 4162, 4156, 87, 87, 4157, 87, 87, 4163, 4166, + 4165, 4161, 87, 4167, 87, 4159, 4160, 4164, 87, 4169, + 87, 4170, 87, 87, 4174, 87, 4168, 4171, 4175, 87, + 4172, 87, 87, 4173, 4177, 87, 4176, 4178, 87, 87, + + 87, 87, 4179, 87, 4184, 87, 4180, 87, 4182, 87, + 87, 87, 87, 87, 4186, 4187, 87, 4190, 87, 4181, + 4183, 4191, 87, 87, 4194, 87, 4185, 4195, 87, 87, + 4188, 4189, 4192, 4197, 87, 87, 4196, 4193, 4198, 87, + 87, 87, 4199, 87, 4202, 4200, 4201, 4204, 87, 4205, + 87, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, + 4206, 4206, 4203, 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 + 81, 81, 90, 90, 4206, 90, 90, 90, 90, 165, + 165, 4206, 4206, 4206, 165, 165, 167, 167, 4206, 4206, + 167, 4206, 167, 169, 4206, 4206, 4206, 4206, 4206, 169, + 172, 172, 4206, 4206, 4206, 172, 172, 174, 4206, 4206, + 4206, 4206, 4206, 174, 176, 176, 4206, 176, 176, 176, + 176, 179, 4206, 4206, 4206, 4206, 4206, 179, 182, 182, + 4206, 4206, 4206, 182, 182, 91, 91, 4206, 91, 91, + 91, 91, 17, 4206, 4206, 4206, 4206, 4206, 4206, 4206, + 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, + + 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, + 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, + 4206, 4206, 4206 } ; -static yyconst flex_int16_t yy_chk[8064] = +static yyconst flex_int16_t yy_chk[8224] = { 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, @@ -2693,13 +2741,13 @@ static yyconst flex_int16_t yy_chk[8064] 5, 3, 6, 24, 4, 24, 24, 5, 24, 6, 7, 7, 7, 7, 24, 7, 8, 8, 8, 8, 33, 8, 7, 9, 9, 9, 26, 26, 8, 10, - 10, 10, 19, 29, 9, 33, 19, 29, 4125, 35, + 10, 10, 19, 29, 9, 33, 19, 29, 4214, 35, 10, 11, 11, 11, 11, 11, 11, 13, 13, 13, 13, 34, 13, 11, 35, 101, 34, 29, 38, 13, 46, 46, 11, 12, 12, 12, 12, 12, 12, 14, 14, 14, 14, 101, 14, 12, 15, 15, 15, 38, - 23, 14, 23, 23, 12, 23, 3282, 15, 16, 16, + 23, 14, 23, 23, 12, 23, 3355, 15, 16, 16, 16, 23, 23, 27, 27, 30, 30, 31, 31, 16, 25, 27, 113, 25, 25, 27, 31, 25, 27, 32, 30, 47, 25, 32, 25, 132, 32, 31, 52, 52, @@ -2709,7 +2757,7 @@ static yyconst flex_int16_t yy_chk[8064] 43, 41, 41, 88, 36, 94, 41, 44, 36, 94, 37, 44, 37, 39, 39, 42, 41, 41, 39, 41, - 42, 44, 39, 42, 57, 44, 44, 57, 39, 1242, + 42, 44, 39, 42, 57, 44, 44, 57, 39, 1260, 42, 39, 45, 45, 42, 42, 93, 45, 39, 93, 63, 45, 63, 63, 74, 63, 68, 68, 71, 95, 71, 71, 73, 71, 73, 73, 95, 73, 74, 80, @@ -2779,9 +2827,9 @@ static yyconst flex_int16_t yy_chk[8064] 356, 357, 179, 356, 354, 358, 360, 345, 350, 351, 368, 360, 360, 351, 357, 374, 353, 358, 351, 368, 359, 351, 359, 359, 363, 363, 351, 351, 351, 351, - 355, 361, 421, 355, 361, 355, 362, 355, 364, 362, + 355, 361, 174, 355, 361, 355, 362, 355, 364, 362, 374, 365, 366, 367, 369, 370, 370, 355, 355, 355, - 421, 355, 375, 369, 371, 364, 365, 366, 364, 371, + 355, 355, 375, 369, 371, 364, 365, 366, 364, 371, 367, 367, 372, 372, 373, 373, 376, 375, 377, 378, 379, 376, 380, 381, 377, 386, 382, 385, 442, 387, @@ -2789,789 +2837,807 @@ static yyconst flex_int16_t yy_chk[8064] 394, 388, 380, 389, 442, 383, 388, 385, 389, 394, 390, 391, 383, 390, 389, 390, 392, 393, 395, 395, 393, 396, 392, 397, 397, 398, 401, 396, 402, 403, - 398, 402, 404, 393, 174, 415, 393, 405, 393, 399, + 398, 402, 404, 393, 172, 415, 393, 405, 393, 399, 399, 408, 399, 410, 403, 411, 401, 404, 399, 402, 407, 405, 399, 407, 411, 408, 415, 399, 410, 416, - 399, 400, 400, 172, 400, 412, 413, 418, 414, 407, + 399, 400, 400, 171, 400, 412, 413, 418, 414, 407, 412, 412, 413, 419, 414, 417, 418, 400, 416, 422, 400, 414, 400, 420, 400, 409, 423, 409, 409, 420, - 417, 426, 419, 424, 429, 427, 426, 409, 409, 409, - 409, 409, 425, 428, 409, 422, 423, 424, 425, 429, - 432, 430, 425, 431, 426, 427, 430, 435, 431, 436, - 433, 434, 434, 428, 437, 432, 433, 438, 439, 440, - 441, 436, 445, 443, 446, 440, 449, 435, 443, 171, - 447, 438, 437, 448, 444, 444, 439, 444, 451, 450, - 449, 450, 445, 451, 446, 441, 447, 456, 452, 448, - 452, 452, 453, 454, 455, 455, 453, 454, 457, 458, - 459, 461, 460, 466, 469, 463, 456, 466, 452, 461, - - 461, 463, 454, 457, 465, 458, 460, 464, 459, 465, - 169, 461, 467, 461, 462, 469, 464, 468, 470, 462, - 473, 467, 471, 468, 470, 473, 471, 462, 462, 474, - 472, 462, 462, 472, 476, 462, 475, 475, 477, 477, - 478, 479, 480, 481, 481, 482, 479, 476, 483, 474, - 484, 482, 485, 483, 484, 480, 486, 487, 488, 478, - 489, 489, 487, 488, 490, 491, 492, 485, 493, 489, - 494, 495, 496, 494, 497, 500, 490, 486, 499, 497, - 493, 498, 499, 495, 492, 491, 498, 500, 501, 501, - 502, 503, 505, 496, 507, 502, 504, 504, 508, 508, - - 507, 510, 511, 512, 513, 514, 515, 516, 517, 521, - 511, 515, 503, 513, 505, 519, 520, 522, 523, 524, - 517, 525, 510, 522, 512, 524, 514, 516, 167, 521, - 526, 529, 523, 519, 520, 519, 527, 525, 528, 526, - 525, 530, 527, 528, 531, 529, 532, 531, 533, 530, - 534, 535, 530, 536, 539, 537, 538, 535, 537, 534, - 532, 540, 538, 533, 541, 543, 540, 542, 539, 543, - 544, 545, 547, 536, 546, 548, 545, 547, 549, 550, - 538, 553, 554, 557, 165, 555, 541, 544, 542, 546, - 556, 548, 550, 559, 556, 572, 572, 549, 551, 551, - - 555, 553, 557, 554, 551, 558, 551, 560, 562, 559, - 558, 560, 551, 564, 551, 563, 561, 551, 551, 565, - 563, 561, 567, 562, 551, 561, 568, 566, 565, 564, - 570, 569, 564, 566, 569, 571, 573, 567, 566, 575, - 563, 577, 568, 574, 574, 576, 578, 578, 579, 580, - 582, 583, 587, 570, 575, 571, 577, 576, 581, 582, - 584, 573, 585, 581, 587, 588, 592, 579, 585, 589, - 583, 580, 590, 589, 588, 584, 590, 591, 592, 593, - 594, 595, 596, 591, 598, 597, 599, 601, 596, 601, - 599, 600, 602, 603, 593, 595, 604, 604, 606, 594, - - 597, 603, 598, 605, 600, 607, 608, 609, 611, 605, - 606, 607, 608, 612, 610, 613, 602, 610, 616, 609, - 613, 614, 611, 615, 617, 614, 615, 632, 612, 618, - 632, 620, 619, 617, 621, 621, 616, 619, 619, 629, - 617, 622, 622, 617, 620, 618, 623, 624, 623, 625, - 625, 626, 626, 624, 627, 630, 628, 629, 631, 633, - 627, 628, 628, 634, 633, 635, 636, 637, 638, 636, - 631, 639, 637, 635, 640, 641, 630, 642, 640, 643, - 644, 641, 634, 643, 645, 646, 647, 647, 648, 645, - 639, 638, 649, 651, 652, 650, 653, 642, 644, 646, - - 650, 654, 658, 648, 655, 656, 691, 654, 86, 655, - 652, 660, 651, 649, 657, 661, 653, 657, 691, 656, - 658, 664, 657, 659, 659, 657, 657, 662, 663, 660, - 665, 661, 662, 663, 667, 664, 668, 667, 669, 672, - 670, 673, 668, 670, 671, 665, 673, 669, 671, 674, - 675, 676, 674, 677, 678, 675, 679, 680, 672, 681, - 685, 678, 680, 682, 682, 683, 684, 676, 686, 679, - 671, 677, 687, 686, 683, 685, 688, 690, 689, 681, - 694, 692, 693, 694, 696, 684, 690, 692, 693, 697, - 688, 699, 697, 687, 689, 695, 695, 698, 695, 700, - - 696, 701, 698, 702, 703, 704, 708, 705, 702, 699, - 706, 704, 705, 700, 707, 701, 706, 707, 710, 709, - 711, 713, 712, 703, 709, 711, 711, 715, 714, 718, - 719, 708, 717, 81, 710, 712, 713, 714, 717, 719, - 715, 716, 720, 721, 716, 723, 716, 720, 718, 722, - 722, 724, 723, 716, 725, 727, 726, 725, 724, 716, - 716, 716, 726, 721, 728, 729, 731, 727, 733, 728, - 729, 729, 725, 730, 730, 732, 734, 732, 734, 728, - 735, 736, 737, 740, 738, 739, 741, 733, 743, 742, - 744, 731, 741, 742, 745, 746, 747, 743, 751, 736, - - 737, 735, 738, 740, 739, 744, 749, 748, 750, 745, - 748, 752, 753, 746, 750, 747, 754, 755, 751, 748, - 756, 749, 757, 758, 753, 752, 757, 759, 760, 761, - 762, 763, 764, 766, 766, 754, 76, 764, 755, 756, - 765, 758, 768, 759, 769, 771, 760, 761, 761, 762, - 763, 767, 772, 770, 765, 767, 768, 772, 773, 771, - 774, 776, 775, 769, 770, 777, 778, 779, 776, 782, - 777, 780, 781, 778, 773, 775, 780, 781, 783, 774, - 784, 785, 788, 786, 787, 783, 793, 782, 75, 784, - 789, 779, 786, 787, 788, 785, 789, 790, 791, 792, - - 793, 791, 790, 792, 794, 795, 796, 797, 798, 796, - 799, 799, 801, 794, 800, 800, 803, 801, 801, 802, - 795, 797, 805, 800, 802, 803, 806, 807, 808, 798, - 809, 810, 806, 811, 809, 812, 813, 815, 814, 816, - 817, 805, 813, 810, 814, 815, 807, 817, 808, 818, - 819, 820, 827, 812, 816, 823, 826, 830, 811, 826, - 833, 836, 831, 835, 838, 838, 830, 818, 831, 827, - 823, 820, 835, 834, 841, 819, 821, 836, 821, 834, - 837, 821, 833, 840, 837, 821, 839, 839, 821, 842, - 843, 844, 841, 848, 840, 821, 821, 844, 821, 846, - - 847, 851, 849, 842, 850, 847, 857, 854, 850, 856, - 843, 845, 845, 845, 848, 845, 69, 852, 845, 846, - 849, 852, 853, 845, 856, 851, 854, 853, 855, 845, - 845, 857, 845, 855, 859, 858, 860, 852, 858, 859, - 859, 861, 861, 860, 862, 863, 864, 864, 865, 866, - 863, 867, 866, 865, 868, 868, 867, 870, 869, 862, - 869, 871, 872, 873, 874, 876, 872, 875, 878, 870, - 877, 877, 879, 876, 880, 881, 881, 882, 883, 884, - 871, 873, 886, 878, 874, 885, 875, 886, 880, 893, - 883, 885, 879, 887, 887, 882, 892, 888, 892, 890, - - 891, 884, 888, 888, 890, 894, 891, 893, 895, 896, - 899, 897, 898, 899, 900, 896, 897, 901, 898, 904, - 900, 902, 902, 905, 894, 901, 903, 903, 895, 906, - 907, 905, 908, 909, 910, 907, 908, 904, 911, 912, - 909, 913, 913, 915, 914, 916, 916, 906, 918, 917, - 919, 915, 910, 914, 911, 917, 921, 922, 912, 923, - 926, 924, 925, 927, 934, 921, 918, 928, 929, 919, - 924, 930, 928, 929, 933, 922, 931, 925, 927, 931, - 930, 932, 935, 936, 926, 923, 932, 937, 933, 934, - 938, 935, 937, 937, 939, 939, 936, 940, 941, 942, - - 943, 944, 945, 953, 938, 945, 949, 947, 942, 947, - 948, 948, 940, 945, 951, 950, 952, 941, 954, 944, - 950, 952, 955, 953, 943, 956, 958, 949, 957, 959, - 960, 961, 963, 959, 962, 951, 965, 957, 954, 964, - 962, 963, 966, 967, 955, 956, 969, 968, 960, 958, - 961, 964, 965, 968, 969, 970, 973, 967, 971, 972, - 972, 966, 974, 971, 975, 976, 977, 978, 979, 970, - 980, 981, 982, 975, 977, 973, 988, 983, 984, 985, - 986, 987, 974, 983, 984, 976, 986, 978, 989, 980, - 979, 981, 982, 985, 989, 987, 988, 990, 991, 992, - - 993, 994, 991, 990, 995, 997, 994, 996, 996, 998, - 999, 997, 993, 999, 1000, 998, 1001, 1002, 992, 1003, - 993, 1004, 1004, 1002, 1005, 995, 1007, 1006, 1013, 1001, - 1008, 1007, 1000, 1008, 1010, 1012, 1012, 1011, 1009, 1003, - 1006, 1011, 1005, 1009, 1009, 1014, 1008, 1015, 1008, 1010, - 1013, 1016, 1017, 1019, 1020, 1021, 1016, 1023, 1021, 1024, - 1025, 1027, 1015, 1028, 1028, 1014, 1027, 1032, 1020, 1021, - 1023, 1017, 1029, 1030, 1031, 1031, 1029, 1019, 1036, 1024, - 1034, 1025, 1026, 1037, 1035, 1026, 1090, 1026, 1030, 1090, - 1033, 1026, 1032, 1026, 1033, 1033, 1036, 1037, 1026, 1035, - - 1034, 1038, 1039, 1026, 1040, 1041, 1038, 1042, 1043, 1040, - 1040, 1044, 1043, 1046, 1041, 1047, 1039, 1045, 1045, 1048, - 1047, 1042, 1045, 1050, 1043, 1046, 1044, 1049, 1049, 1051, - 1052, 1053, 1045, 1048, 1054, 1056, 1053, 1055, 1061, 1052, - 1054, 1056, 1055, 1051, 1050, 1057, 1058, 1058, 1059, 1060, - 1062, 1057, 1063, 1059, 1065, 1060, 1066, 1069, 1069, 1067, - 1061, 1066, 1068, 1070, 1072, 1073, 1065, 1071, 1070, 1062, - 1063, 1064, 1064, 1067, 1068, 1071, 1075, 1064, 1072, 1064, - 1074, 1073, 1076, 1077, 1079, 1064, 1078, 1081, 1080, 1079, - 1064, 1064, 1078, 1082, 1074, 1075, 1083, 1064, 1084, 1077, - - 1080, 1076, 1085, 1085, 1086, 1081, 1087, 1089, 1086, 1082, - 1091, 1093, 1092, 1089, 1083, 1094, 1084, 1092, 1095, 1096, - 1100, 1094, 1098, 1095, 1093, 1099, 1087, 1101, 1102, 1091, - 1103, 1098, 1104, 1101, 1099, 1105, 1100, 1106, 1096, 1103, - 1105, 1107, 1108, 1108, 1109, 1111, 1110, 1112, 1114, 1102, - 1120, 1104, 1117, 1113, 1111, 1107, 1112, 1106, 1110, 1113, - 1115, 1119, 1121, 1121, 1109, 1114, 1115, 1122, 1117, 1123, - 1120, 1124, 1125, 1126, 1123, 1119, 1127, 1124, 1128, 1129, - 1130, 1133, 64, 1134, 1129, 1130, 1133, 1126, 1134, 1135, - 1143, 1125, 1122, 1128, 1127, 1136, 1136, 1137, 1135, 1138, - - 1139, 1140, 1141, 1137, 1147, 1138, 1143, 1144, 1149, 1139, - 1146, 1146, 1144, 1144, 1146, 1141, 1140, 1148, 1150, 1147, - 1148, 1151, 1149, 1152, 1155, 1165, 1151, 1153, 1154, 1156, - 1157, 1155, 1159, 1158, 1161, 1163, 1160, 1169, 1150, 1165, - 1153, 1153, 1160, 1152, 1154, 1156, 1158, 1159, 1157, 1162, - 1163, 1164, 1167, 1167, 1161, 1162, 1164, 1168, 1169, 1170, - 1168, 1171, 1172, 1173, 1170, 1174, 1171, 1176, 1175, 1178, - 1174, 1179, 1173, 1175, 1180, 1178, 1181, 1182, 1172, 1176, - 1180, 1183, 1183, 1182, 1184, 1185, 1186, 1179, 1188, 1186, - 1187, 1187, 1189, 1184, 1190, 1191, 1192, 1181, 1191, 1193, - - 59, 1194, 1195, 1185, 1203, 1193, 1188, 1194, 1195, 1192, - 1196, 1189, 1197, 1198, 1190, 1196, 1199, 1197, 1200, 1198, - 1202, 1199, 1203, 1204, 1200, 1202, 1205, 1208, 1206, 1207, - 1207, 1209, 1205, 1206, 1210, 1211, 1208, 1212, 1213, 1210, - 1209, 1213, 1214, 1204, 1215, 1214, 1216, 1217, 1218, 1219, - 58, 1216, 1220, 1211, 1222, 1215, 1212, 1221, 1220, 1223, - 1218, 1224, 1224, 1221, 1223, 1217, 1225, 1226, 1219, 1222, - 1227, 1228, 1229, 1230, 1231, 1232, 1229, 1233, 1235, 1236, - 1241, 1226, 1227, 1231, 1238, 1225, 1237, 1237, 1236, 1228, - 1239, 1230, 1238, 1240, 1232, 1239, 1243, 1235, 1240, 1244, - - 1241, 1245, 1233, 1246, 1248, 1250, 1247, 1259, 1246, 1254, - 1243, 1249, 1249, 1245, 1244, 1247, 1251, 1252, 1253, 1248, - 1255, 1259, 1251, 1252, 1254, 1250, 1253, 1256, 1257, 1258, - 1257, 1260, 1256, 1261, 1258, 1262, 1255, 1263, 1261, 1264, - 1265, 1267, 1264, 1266, 1273, 1260, 1272, 1265, 1269, 1269, - 1262, 1270, 1277, 1271, 1275, 1272, 1263, 1271, 1266, 1284, - 1267, 1274, 1273, 1278, 1276, 1270, 1284, 1274, 1278, 1275, - 1276, 1280, 1277, 1281, 1281, 1280, 1282, 1278, 1285, 1278, - 1286, 1282, 1278, 1283, 1283, 1287, 1288, 1290, 1287, 1289, - 1292, 1285, 1293, 1295, 1286, 1292, 1290, 1294, 1296, 1295, - - 1297, 1298, 1299, 1296, 1304, 1288, 1306, 1289, 1302, 1294, - 1306, 1293, 1298, 1302, 1297, 1301, 1301, 1303, 1305, 1307, - 1308, 1299, 1303, 1305, 1304, 1309, 1310, 1311, 1307, 1312, - 1311, 1313, 1315, 1316, 1314, 1308, 1318, 1317, 1313, 1311, - 1309, 1319, 1318, 1321, 1312, 1310, 1314, 1320, 1322, 1321, - 1323, 1315, 1324, 1327, 1316, 1317, 1319, 1325, 1320, 1326, - 1328, 1324, 1329, 1332, 1338, 1327, 1330, 1331, 1322, 1320, - 1323, 1334, 1325, 1331, 1335, 1339, 1336, 1334, 1326, 1328, - 1337, 1330, 1341, 1332, 1338, 1343, 1344, 1329, 1337, 1335, - 1336, 1339, 1340, 1342, 1341, 1345, 1439, 1340, 1342, 1342, - - 1344, 1346, 1346, 1348, 1343, 1348, 1349, 1350, 1345, 1347, - 1347, 1352, 1352, 1439, 1347, 1351, 1350, 1347, 1347, 1349, - 1353, 1351, 1347, 1354, 1355, 1353, 1357, 1354, 1347, 1356, - 1360, 1357, 1347, 1355, 1358, 1356, 1359, 1359, 1363, 1358, - 1361, 1361, 1362, 1364, 1365, 1362, 1366, 1362, 1367, 1361, - 1368, 1360, 1366, 1368, 1367, 1369, 1365, 1370, 1363, 1372, - 1371, 1364, 1373, 1374, 1369, 1371, 1375, 1378, 1376, 1374, - 1377, 1378, 1375, 1372, 1376, 1377, 1379, 1370, 1380, 1381, - 1373, 1382, 1383, 1383, 1381, 1384, 1384, 1380, 1384, 1379, - 1385, 1388, 1380, 1387, 1380, 1382, 1380, 1387, 1380, 1389, - - 1390, 1385, 1391, 1392, 1392, 1399, 1388, 1393, 1393, 1394, - 1395, 1391, 1396, 1397, 1394, 1394, 1398, 1399, 1390, 1389, - 1400, 1402, 1397, 1395, 1401, 1398, 1396, 1403, 1404, 1401, - 1405, 1406, 1407, 1408, 1408, 1402, 1403, 1414, 1407, 1409, - 1410, 1411, 1400, 1415, 1413, 1406, 1414, 1404, 1410, 1405, - 1415, 1409, 1412, 1416, 1417, 1411, 1418, 1412, 1413, 1419, - 1419, 1418, 1420, 1421, 1421, 1422, 1423, 1427, 1423, 1425, - 1422, 1416, 1425, 1426, 1428, 1429, 1429, 1420, 1426, 1417, - 1430, 1431, 1431, 1428, 1432, 1432, 1427, 1433, 1434, 1435, - 1436, 53, 1433, 1437, 1437, 1438, 1440, 1441, 1442, 1440, - - 1430, 1443, 1446, 1444, 1442, 1445, 1443, 1445, 1449, 1434, - 1435, 1436, 1444, 1448, 1450, 1438, 1448, 1441, 1452, 1451, - 1446, 1453, 1454, 1449, 1451, 48, 1453, 1450, 1455, 1460, - 1454, 1456, 1452, 1455, 1456, 1457, 1458, 1458, 1459, 1461, - 1457, 1462, 1463, 1459, 1465, 1461, 1466, 1460, 1462, 1467, - 1465, 1468, 1466, 1469, 1467, 1463, 1468, 1470, 1471, 1469, - 1472, 1473, 1473, 1474, 1475, 1477, 1470, 1478, 1479, 1481, - 1477, 1472, 1480, 1482, 1483, 1484, 1485, 1471, 1479, 1486, - 1483, 1484, 1485, 1474, 1475, 1478, 1488, 1480, 1489, 1481, - 1486, 1490, 1488, 1491, 1492, 1493, 1482, 1494, 1491, 1495, - - 1492, 1496, 1489, 1497, 1497, 1490, 1498, 1499, 1489, 1494, - 1500, 1490, 1501, 1495, 1504, 1493, 1502, 1501, 1505, 1496, - 1503, 1503, 1507, 1505, 1508, 1510, 1498, 1509, 1500, 1511, - 1510, 1510, 1499, 1512, 1502, 1513, 1524, 1504, 1508, 1515, - 1509, 1507, 1514, 1516, 1513, 1517, 1519, 1511, 1521, 1518, - 1514, 1512, 1524, 1515, 1518, 1519, 1526, 1518, 1516, 1520, - 1517, 1520, 1521, 1517, 1523, 1525, 1527, 1526, 1528, 1525, - 1523, 1527, 1527, 1529, 1530, 1531, 1532, 1533, 1534, 1536, - 1531, 1532, 1533, 1535, 1536, 1537, 1539, 1528, 1540, 1541, - 1542, 1542, 1530, 1543, 1544, 1545, 1534, 1543, 1546, 1529, - - 1539, 1547, 1548, 1535, 1546, 1537, 1540, 1541, 1549, 1550, - 1551, 1552, 1544, 1547, 1545, 1553, 1554, 1555, 1548, 1557, - 1560, 1554, 1558, 1550, 1555, 1551, 1552, 1549, 1556, 1561, - 1559, 1562, 1562, 1556, 1553, 1559, 1558, 1557, 1561, 1563, - 1564, 1560, 1565, 1566, 1566, 1567, 1568, 1569, 1573, 1564, - 1574, 1567, 1568, 1572, 1563, 1570, 1570, 1571, 1571, 1572, - 1575, 1569, 1565, 1576, 1573, 1575, 1577, 1578, 1585, 1576, - 1586, 1574, 1577, 1578, 1579, 1579, 1580, 1580, 1582, 1582, - 1583, 1584, 1586, 1587, 1583, 1588, 1585, 1589, 1590, 1590, - 1584, 1591, 1595, 1592, 1589, 1596, 1580, 1587, 1580, 1593, - - 1588, 1592, 1594, 1597, 1600, 1593, 1595, 1594, 1597, 1597, - 1598, 1591, 1602, 1599, 1596, 1598, 1598, 1599, 1601, 1601, - 1603, 1604, 1605, 1606, 1600, 1607, 1608, 1605, 1610, 1609, - 1604, 1602, 1611, 1613, 1610, 1612, 1614, 1611, 1615, 1603, - 1616, 1612, 1606, 1617, 1607, 1618, 1608, 1609, 1619, 1617, - 1621, 1613, 1620, 1615, 1619, 1623, 1614, 1624, 1620, 1622, - 1625, 1626, 1628, 1627, 1618, 1632, 1616, 1629, 1622, 1621, - 1630, 1630, 1631, 1633, 1623, 1631, 1624, 1627, 1634, 1625, - 1626, 1640, 1629, 1628, 1632, 1635, 1635, 1636, 1636, 1637, - 1634, 1638, 1633, 1639, 1637, 1638, 1640, 1642, 1641, 1645, - - 18, 1645, 1647, 1647, 1648, 1645, 1639, 1641, 1649, 1648, - 1642, 1650, 1651, 1653, 1650, 1652, 1654, 1655, 1645, 1657, - 1652, 1651, 1656, 1656, 1657, 1658, 1649, 1659, 1653, 1661, - 1660, 1658, 1662, 1655, 1663, 1661, 1654, 1662, 1663, 1665, - 1664, 1667, 1659, 1660, 1664, 1666, 1668, 1669, 1670, 1670, - 1667, 1672, 1674, 1669, 1675, 1676, 1677, 1677, 1674, 1665, - 1676, 1678, 1679, 1666, 1681, 1681, 1668, 1678, 1683, 1672, - 1685, 1683, 1684, 1684, 1686, 1675, 1687, 1689, 1690, 1692, - 1689, 1691, 1679, 1693, 1694, 1694, 1685, 1695, 1692, 1696, - 1686, 1698, 1687, 1697, 1699, 1703, 1698, 1706, 1700, 1690, - - 1702, 1691, 1695, 1693, 1700, 1701, 1701, 1704, 1699, 1702, - 1696, 1705, 1697, 1703, 1707, 1707, 1708, 1706, 1710, 1709, - 1711, 1714, 1704, 1710, 1712, 1712, 1716, 1713, 1715, 1715, - 1708, 1713, 1717, 1718, 1719, 1711, 1705, 1709, 1719, 1720, - 1721, 1714, 1723, 1723, 1718, 1721, 1725, 1724, 1716, 1725, - 1726, 1717, 1724, 1724, 1727, 1728, 1729, 1731, 1720, 1727, - 1733, 1730, 1736, 1726, 1732, 1735, 1735, 1736, 1737, 1739, - 1734, 1728, 1741, 1743, 1729, 1730, 1731, 1731, 1732, 1734, - 1740, 1738, 1743, 1740, 1745, 1733, 1738, 1749, 1737, 1739, - 1744, 1741, 1742, 1742, 1746, 1744, 1746, 1747, 1751, 1748, - - 1750, 1753, 1747, 1751, 1745, 1748, 1750, 1749, 1754, 1754, - 1755, 1756, 1757, 1758, 1762, 1753, 1760, 1757, 1761, 1758, - 1765, 1760, 1766, 1761, 1763, 1763, 1764, 1764, 1767, 1755, - 1756, 1770, 1768, 1771, 1765, 1768, 1769, 1769, 1762, 1772, - 1766, 1774, 1775, 1767, 1773, 1771, 1776, 1773, 1775, 1770, - 1773, 1776, 1777, 1774, 1779, 1777, 1780, 1781, 17, 1772, - 1784, 1780, 1773, 1779, 1782, 1783, 1783, 1782, 1785, 1786, - 1790, 1777, 1787, 1792, 1785, 1786, 1790, 1787, 1788, 1788, - 1789, 1789, 1781, 1791, 1784, 1793, 1792, 1794, 1791, 1795, - 1796, 1797, 1798, 1796, 1799, 1802, 1800, 1797, 1798, 1801, - - 1799, 1800, 1803, 1793, 1806, 1801, 1794, 1803, 1805, 1795, - 1804, 1804, 1807, 1805, 1808, 1809, 1810, 1811, 1802, 1816, - 1812, 1820, 1806, 1815, 1813, 1814, 1817, 1819, 1820, 1808, - 1817, 1822, 1807, 1809, 1812, 1810, 1823, 1811, 1813, 1814, - 1818, 1815, 1818, 1822, 1816, 1824, 1819, 1825, 1823, 1826, - 1827, 1828, 1830, 1825, 1829, 1830, 1831, 1831, 1824, 1834, - 1834, 1832, 1835, 1837, 1838, 1838, 1827, 1836, 1829, 1826, - 1832, 1828, 1836, 1830, 1839, 1837, 1840, 1841, 1842, 1843, - 1844, 1848, 1835, 1844, 1845, 1846, 1847, 1850, 1843, 1839, - 1840, 1852, 1846, 1853, 1844, 1847, 1842, 1848, 1847, 1845, - - 1854, 1841, 1850, 1854, 1855, 1855, 1858, 1850, 1857, 1852, - 1856, 1856, 1859, 1860, 1862, 1859, 1861, 1861, 1853, 1863, - 1857, 1864, 1865, 1868, 1858, 1866, 1864, 1862, 1860, 1867, - 1866, 1869, 1867, 1870, 1871, 1873, 1869, 1872, 1863, 1865, - 1875, 1879, 1876, 1877, 1868, 1880, 1872, 1874, 1879, 1877, - 1871, 1876, 1870, 1881, 1873, 1882, 1874, 1878, 1878, 1874, - 1883, 1884, 1885, 1890, 1875, 1880, 1881, 1885, 1885, 1887, - 1886, 1891, 0, 1882, 1883, 1886, 1894, 1884, 1892, 1892, - 1893, 1887, 1895, 1893, 1899, 1896, 1896, 1898, 1890, 1891, - 1896, 1895, 1894, 1897, 1897, 1904, 1898, 1900, 1899, 1898, - - 1900, 1901, 1902, 1902, 1903, 1905, 1901, 1903, 1897, 1906, - 1907, 1909, 1911, 1904, 1910, 1907, 1907, 1912, 1913, 1915, - 1916, 1916, 1912, 1918, 1914, 1909, 1905, 1906, 1918, 1910, - 1914, 1919, 1913, 1917, 1911, 1920, 1921, 1915, 1923, 1917, - 1924, 1920, 1921, 1925, 1926, 1919, 1927, 1929, 1931, 1933, - 1926, 1934, 1928, 1929, 1935, 1928, 1931, 1925, 1923, 1927, - 1924, 1928, 1937, 1936, 1939, 1938, 1940, 1937, 1933, 1941, - 1934, 1936, 1942, 1935, 1938, 1940, 1943, 1939, 1944, 1944, - 1948, 1945, 1941, 1946, 1950, 1947, 1942, 1945, 1947, 1946, - 1943, 1949, 1949, 1948, 1951, 1952, 1953, 1953, 1954, 1955, - - 1944, 1956, 1957, 1958, 1950, 1955, 1960, 1960, 1961, 1962, - 1963, 1954, 1951, 1962, 1952, 1963, 1964, 1965, 1957, 1966, - 1967, 1958, 1965, 1956, 1966, 1968, 1972, 1970, 1961, 1967, - 1970, 1973, 1974, 1975, 1976, 1974, 1964, 1972, 1977, 1977, - 1973, 1970, 1978, 1979, 1980, 1975, 1981, 1981, 1968, 1976, - 1983, 1982, 1984, 1985, 1987, 1979, 1982, 1988, 1989, 1984, - 1986, 1978, 1991, 1980, 1983, 1985, 1987, 1986, 1988, 1992, - 1993, 1994, 1995, 1996, 1997, 1997, 1993, 1998, 1989, 1996, - 1998, 1991, 1999, 1994, 2000, 2000, 2002, 2003, 2004, 1992, - 1995, 2002, 2005, 2003, 2006, 2008, 2008, 2009, 2007, 2012, - - 2013, 2005, 1999, 2004, 2007, 2010, 2014, 2010, 2011, 2009, - 2006, 2011, 2015, 2016, 2018, 2017, 2019, 2020, 2016, 2012, - 2017, 2021, 2013, 2018, 2014, 2024, 2021, 2023, 2019, 2022, - 2015, 2027, 2020, 2026, 2022, 2025, 2023, 2029, 2026, 2030, - 2025, 2028, 2028, 2029, 2033, 2024, 2027, 2025, 2032, 2023, - 2034, 2035, 2036, 2037, 2038, 2037, 2039, 2039, 2040, 2040, - 2030, 2041, 2041, 2033, 2032, 2042, 2045, 2035, 2038, 2034, - 2038, 2046, 2036, 2043, 2043, 2044, 2044, 2047, 2048, 2048, - 2049, 2054, 2050, 2051, 2049, 2042, 2051, 2045, 2050, 2053, - 2055, 2056, 2046, 2057, 2059, 2053, 2055, 2062, 2047, 2054, - - 2058, 2060, 2057, 2063, 2060, 2058, 2061, 2061, 2063, 2064, - 2064, 2065, 2066, 2067, 2056, 2068, 2073, 2062, 2067, 2059, - 2068, 2069, 2069, 2070, 2071, 2072, 2065, 2074, 2070, 2075, - 2071, 2077, 2078, 2066, 2076, 2079, 2073, 2072, 2072, 2072, - 2076, 2080, 2079, 2083, 2072, 2074, 2080, 2084, 2082, 2075, - 2086, 2077, 2078, 2082, 2082, 2087, 2085, 2083, 2085, 2088, - 2089, 2086, 2084, 2090, 2091, 2088, 2092, 2093, 2095, 2089, - 2087, 2094, 2094, 2096, 2096, 2097, 2098, 2102, 2091, 2099, - 2099, 2100, 2100, 2090, 2106, 2092, 2101, 2101, 2093, 2105, - 2105, 2107, 2108, 2108, 2095, 2097, 2110, 2102, 2098, 2111, - - 2107, 2112, 2113, 2114, 2116, 2110, 2118, 2112, 2115, 2106, - 2117, 2117, 2120, 2119, 2122, 2125, 2121, 2126, 2116, 2120, - 2111, 2129, 2114, 2113, 2115, 2121, 2129, 2118, 2119, 2123, - 2123, 2124, 2124, 2126, 2131, 0, 2128, 2130, 2132, 2136, - 2122, 2125, 2128, 2130, 2133, 2132, 2134, 2137, 2134, 2141, - 2133, 2138, 2138, 2137, 2131, 2139, 2140, 2142, 2136, 2143, - 2139, 2145, 2147, 2144, 2141, 2140, 2144, 2146, 2148, 2151, - 2146, 2149, 2149, 2145, 2153, 2150, 2152, 2142, 2143, 2150, - 2147, 2155, 2152, 2154, 2154, 2156, 2153, 2155, 2157, 2151, - 2160, 2158, 2161, 2162, 2148, 2158, 2163, 2163, 2162, 2164, - - 2165, 2166, 2168, 2157, 2169, 2156, 2170, 2170, 2169, 2171, - 2160, 2158, 2178, 2172, 2161, 2171, 2166, 2173, 2173, 2165, - 2174, 2168, 2172, 2164, 2175, 2176, 2177, 2177, 2175, 2174, - 2179, 2180, 2181, 2178, 2182, 2183, 2176, 2181, 2184, 2185, - 2189, 2176, 2186, 2188, 2179, 2185, 2187, 2196, 2188, 0, - 2180, 2190, 2190, 2189, 2182, 2183, 2191, 2191, 2184, 2192, - 2186, 2187, 2194, 2192, 2195, 2197, 2205, 2196, 2198, 2198, - 2197, 2194, 2200, 2200, 2206, 2195, 2201, 2202, 2204, 2206, - 2195, 2201, 2201, 2202, 2204, 2207, 2210, 2208, 2212, 2214, - 2211, 2216, 2205, 2208, 2211, 2213, 2213, 2207, 2210, 2215, - - 2212, 2217, 2218, 2219, 2221, 2215, 2222, 2217, 2219, 2220, - 2220, 2223, 2224, 2216, 2214, 2226, 2223, 2218, 2227, 0, - 2228, 2230, 2230, 2221, 2224, 2228, 2222, 2226, 2231, 2232, - 2232, 2231, 2233, 2233, 2234, 2234, 2236, 2227, 2235, 2235, - 2237, 2238, 2236, 2239, 2240, 2243, 2241, 2242, 2250, 2239, - 2240, 2241, 2245, 2242, 2243, 2237, 2248, 2245, 2246, 2248, - 2251, 2238, 2249, 2246, 2246, 2252, 2249, 2253, 2253, 2250, - 2255, 2256, 2251, 2257, 2258, 2258, 2259, 2264, 2257, 2260, - 2252, 2261, 2255, 2256, 2260, 2259, 2261, 2262, 2263, 2263, - 2262, 2265, 2266, 2267, 2269, 2268, 2271, 2264, 2269, 2270, - - 2265, 2268, 2271, 2272, 2270, 2273, 2274, 2278, 2275, 2279, - 2266, 2280, 2267, 2281, 2273, 2277, 2277, 2283, 2279, 2284, - 2280, 2272, 2275, 2285, 2274, 2278, 2283, 2277, 2282, 2282, - 2286, 2284, 2287, 2281, 2293, 2286, 2290, 2290, 2292, 2294, - 2295, 2292, 2297, 2299, 2285, 2287, 2298, 2300, 2303, 2299, - 2293, 2301, 2301, 2305, 0, 2294, 2295, 2297, 2312, 2302, - 2298, 2302, 2303, 2304, 2300, 2306, 2306, 2307, 2313, 2304, - 2317, 2305, 2309, 2309, 2313, 2307, 2310, 2310, 2314, 2315, - 2316, 2312, 2318, 2321, 2314, 2319, 2319, 2316, 2320, 2320, - 2324, 2322, 2317, 2315, 2323, 2325, 2326, 2320, 2328, 2327, - - 2330, 2337, 2318, 2322, 2321, 2324, 2323, 2325, 2327, 2329, - 2333, 2334, 2338, 2328, 2329, 2329, 2335, 0, 2331, 2337, - 2331, 2331, 2326, 2330, 2331, 2336, 2336, 2343, 2335, 2346, - 2333, 2346, 2338, 2339, 2334, 2340, 2339, 2331, 2341, 2341, - 2340, 2342, 2342, 2345, 2347, 2348, 2349, 2343, 2345, 2352, - 2348, 2354, 2355, 2349, 2357, 2358, 2359, 2358, 2352, 2360, - 2361, 2355, 2347, 2363, 2362, 2365, 2357, 2365, 2366, 2354, - 2362, 2367, 2367, 2368, 2360, 2359, 2369, 2370, 2374, 2370, - 2361, 2369, 2366, 2363, 2372, 2373, 2375, 2376, 2377, 2372, - 2373, 2380, 2378, 2379, 2377, 2381, 2374, 2378, 2384, 2368, - - 2381, 2381, 2382, 2380, 2375, 2385, 2379, 2376, 2386, 2390, - 2382, 2387, 2387, 2388, 2388, 2389, 2391, 2384, 2393, 2385, - 2386, 2392, 2397, 2393, 2390, 2395, 2389, 2392, 2394, 2396, - 2394, 2395, 2398, 2399, 2400, 2396, 2391, 2402, 2398, 2399, - 2397, 2407, 2400, 2401, 2401, 2403, 2403, 2404, 2404, 2402, - 2400, 2405, 2406, 2410, 2409, 2412, 2414, 2406, 2409, 2407, - 2405, 2411, 2410, 2411, 2413, 2410, 2415, 2416, 2414, 2413, - 2413, 2418, 2420, 2419, 2423, 2415, 2412, 2420, 2421, 2416, - 2424, 2425, 2430, 2421, 2418, 2419, 2427, 2423, 2424, 2428, - 2425, 2426, 2426, 2429, 2431, 2432, 2434, 2433, 2430, 0, - - 2424, 2434, 2436, 2437, 2427, 2438, 2442, 2428, 2439, 2432, - 2448, 2429, 2433, 2439, 2436, 2437, 2440, 2441, 2450, 2431, - 2449, 2440, 2445, 2447, 2442, 2438, 2441, 2451, 2445, 2447, - 2452, 2453, 2453, 2448, 2454, 2449, 2450, 2455, 2455, 2452, - 2456, 2445, 2457, 2454, 2458, 2459, 2460, 2461, 2458, 2462, - 2459, 2464, 2451, 2466, 2465, 2477, 2472, 2468, 2456, 2460, - 2465, 2457, 2461, 2468, 2472, 2470, 2467, 2469, 2470, 2462, - 2464, 2467, 2467, 2469, 2473, 2466, 2475, 2478, 2477, 2479, - 2479, 2481, 2480, 2480, 2482, 2482, 2483, 2483, 2484, 2485, - 2481, 2489, 2486, 2488, 2473, 2478, 2475, 2480, 2486, 2488, - - 2484, 2490, 2492, 0, 2491, 2499, 2489, 2485, 2480, 2491, - 2493, 2493, 2494, 2494, 2495, 2501, 2496, 2503, 2505, 2495, - 2492, 2490, 2496, 2498, 2500, 2499, 2504, 2498, 2500, 2506, - 2507, 2504, 2508, 2509, 2510, 2501, 2511, 2508, 2512, 2513, - 2516, 2505, 2503, 2512, 2506, 2514, 2514, 2517, 2507, 2515, - 2510, 2509, 2517, 2515, 2518, 2516, 2511, 2519, 2520, 2521, - 2522, 2513, 2523, 2525, 2524, 2526, 2526, 2523, 2529, 2530, - 2528, 2521, 2518, 2531, 2532, 2533, 2520, 2524, 2528, 2522, - 0, 2525, 2534, 2519, 2535, 2537, 2536, 2529, 2530, 2538, - 2540, 2539, 2531, 2542, 2544, 2538, 2540, 2532, 2536, 2533, - - 2539, 2534, 2545, 2546, 2548, 2535, 2537, 2544, 2542, 2546, - 2547, 2553, 2547, 2549, 2549, 2550, 2545, 2552, 2551, 2554, - 2550, 2551, 0, 2555, 2548, 2556, 2556, 2557, 2557, 2558, - 2552, 2558, 2560, 2554, 2561, 2553, 2555, 2559, 2559, 2562, - 2563, 2563, 2565, 2565, 2563, 2566, 2566, 2560, 2567, 2561, - 2568, 2568, 2562, 2569, 2570, 2570, 2571, 2571, 2575, 2572, - 2576, 2574, 2569, 2567, 2572, 2569, 2574, 2577, 2578, 2580, - 2580, 2581, 2581, 2582, 2583, 2583, 2584, 2590, 2575, 2577, - 2576, 2578, 2585, 2585, 2586, 2587, 2588, 2588, 2589, 2589, - 2587, 2590, 2582, 2591, 2584, 2592, 2593, 2593, 2596, 2586, - - 2594, 2597, 2591, 2595, 2595, 2599, 2600, 2600, 2601, 2609, - 2599, 2603, 2596, 2602, 2602, 2592, 2604, 2594, 2605, 2606, - 2597, 2604, 2606, 2610, 2605, 2607, 2607, 2601, 2609, 2603, - 2608, 2608, 2611, 2613, 2611, 2614, 2615, 2615, 2610, 2616, - 2618, 2607, 2619, 2620, 2621, 2616, 2622, 2625, 2613, 2624, - 2622, 2623, 2623, 2626, 2614, 2630, 2627, 2619, 2628, 2621, - 2618, 2627, 2628, 2631, 2631, 2634, 2620, 2625, 2624, 2629, - 2630, 2639, 2629, 2626, 2633, 2633, 2635, 2636, 2631, 2637, - 2638, 2629, 2640, 2635, 2646, 2634, 2639, 2642, 2629, 2629, - 2646, 2636, 2641, 2641, 2647, 2653, 2642, 2637, 2638, 2643, - - 2644, 2643, 2648, 2644, 2649, 2650, 2647, 2648, 2640, 2649, - 2650, 2651, 2652, 2654, 2655, 2656, 2653, 2661, 2644, 2655, - 2644, 2658, 2654, 2659, 2660, 2652, 2658, 2662, 2659, 2660, - 2664, 2663, 2661, 2662, 2665, 2667, 2651, 2663, 2666, 2669, - 2667, 2656, 2668, 2670, 2666, 2671, 2672, 2668, 2671, 2665, - 2673, 2664, 2674, 2675, 2676, 2677, 2670, 2682, 2684, 2673, - 0, 2674, 2675, 2676, 2669, 2678, 2672, 2679, 2680, 2677, - 2685, 2678, 2680, 2679, 2686, 2686, 2687, 2682, 2684, 2685, - 2688, 2688, 2687, 2689, 2690, 2694, 2690, 2691, 2693, 2688, - 2692, 2692, 2696, 2693, 2689, 2697, 2691, 2698, 2698, 2699, - - 2700, 2701, 2707, 2705, 2702, 2694, 2706, 2694, 2696, 2700, - 2701, 2697, 2702, 2703, 2699, 2705, 2708, 2707, 2703, 2711, - 2710, 2712, 2706, 2710, 2711, 2713, 2714, 2718, 2708, 2715, - 2715, 2716, 2716, 2739, 2713, 2717, 2717, 2739, 2714, 2719, - 2719, 2712, 2721, 2721, 2723, 2722, 2724, 2718, 2722, 2723, - 2725, 2726, 2724, 2727, 2727, 2728, 2725, 2729, 2729, 2730, - 2726, 2731, 2731, 2732, 2733, 2734, 2734, 2735, 2736, 2728, - 2737, 2730, 2746, 2735, 2752, 2737, 2740, 2732, 2744, 2740, - 2741, 2741, 2736, 2733, 2742, 2743, 2745, 2744, 2749, 2742, - 2743, 2751, 2746, 2747, 2752, 2745, 2751, 2747, 2748, 2748, - - 2753, 2749, 2754, 2755, 2756, 2757, 2758, 2759, 2756, 2760, - 2764, 2758, 2765, 2759, 2766, 2760, 2762, 2755, 2761, 2761, - 2753, 2762, 2754, 2763, 2763, 2757, 2768, 2767, 2764, 2769, - 2769, 2765, 2767, 2766, 2771, 2772, 2773, 2774, 2775, 2781, - 2776, 2773, 2782, 2774, 2775, 2779, 2771, 2768, 2776, 2788, - 2777, 2772, 2777, 2781, 2779, 2790, 2782, 2783, 2783, 2784, - 2785, 2785, 2784, 2787, 2788, 2789, 2787, 2794, 2789, 2791, - 2791, 2794, 2795, 2796, 2797, 2797, 2804, 2798, 2795, 2799, - 2807, 2790, 2802, 2802, 2799, 2796, 2798, 2806, 2810, 2811, - 2812, 2812, 2813, 2810, 2804, 2814, 2807, 2816, 2817, 2818, - - 2818, 2806, 2816, 2817, 2820, 2820, 2822, 2823, 2824, 2824, - 2813, 2826, 2822, 2825, 2827, 2811, 2814, 2829, 2830, 2827, - 2831, 2830, 2832, 2833, 2833, 2835, 2836, 2823, 2839, 2825, - 2840, 2837, 2831, 2826, 2832, 2836, 2829, 2837, 2838, 2842, - 2842, 2835, 2843, 2844, 2838, 2840, 2839, 2845, 2847, 2848, - 2845, 2843, 2844, 2846, 2849, 2846, 2850, 2851, 2852, 2849, - 2860, 2853, 2858, 2847, 2848, 2850, 2855, 2855, 2856, 2856, - 2857, 0, 2859, 2860, 2863, 2857, 2851, 2852, 2852, 2853, - 2858, 2859, 2861, 2862, 2864, 2862, 2866, 2861, 2863, 2865, - 2867, 2866, 2868, 2871, 2869, 2870, 2870, 2875, 2864, 2869, - - 2877, 2865, 2872, 2872, 2873, 2873, 2874, 2874, 2871, 2875, - 2867, 2876, 2868, 2876, 2878, 2879, 2879, 2882, 2877, 2878, - 2880, 2880, 2881, 2881, 2883, 2884, 2885, 2886, 0, 2882, - 2889, 2887, 2888, 2888, 2890, 2890, 2897, 2884, 2891, 2891, - 2892, 2893, 2893, 2894, 2883, 2895, 2885, 2887, 2886, 2889, - 2896, 2892, 2895, 2898, 2899, 2894, 2897, 2900, 2898, 2901, - 2901, 2902, 2896, 2903, 2903, 2904, 2905, 2906, 2907, 2908, - 2902, 2911, 2909, 2910, 2899, 2913, 2912, 2900, 2912, 2916, - 2906, 2909, 2917, 2908, 2919, 2910, 2905, 2913, 2914, 2914, - 2915, 2904, 2907, 2911, 2916, 2920, 2921, 2917, 2922, 2915, - - 2923, 2923, 2919, 2922, 2924, 2925, 2926, 2927, 2925, 2928, - 2929, 2929, 2927, 2931, 2928, 2930, 2930, 2920, 2921, 2936, - 2926, 2932, 2932, 2937, 2937, 2931, 2940, 2924, 2936, 2939, - 2939, 2941, 2942, 2943, 2945, 2946, 2947, 2948, 2950, 2949, - 2951, 2952, 2941, 2952, 2940, 2953, 2954, 2950, 2943, 2955, - 2961, 2942, 0, 2946, 2945, 2956, 2956, 2948, 2947, 2949, - 2951, 2960, 2958, 2967, 2954, 2953, 2958, 2955, 2959, 2959, - 2962, 2965, 2961, 2963, 2963, 2960, 2966, 2966, 2968, 2962, - 2965, 2967, 2969, 2970, 2971, 2972, 2973, 2975, 2976, 2974, - 2970, 2977, 2976, 2981, 2978, 2977, 2968, 2979, 2979, 2971, - - 2969, 2978, 2982, 2972, 2973, 2974, 2975, 2980, 2980, 2983, - 2985, 2985, 2987, 2981, 2988, 2983, 2986, 2986, 2987, 2989, - 2982, 2990, 2991, 2993, 2992, 2994, 2994, 2995, 2993, 2996, - 2997, 2998, 2988, 2999, 3000, 3001, 2990, 2989, 2992, 3007, - 3001, 2991, 2998, 3002, 2999, 3002, 3004, 2995, 3004, 2996, - 2997, 3003, 3003, 3010, 3000, 3005, 3005, 3011, 3007, 3008, - 3008, 3012, 3010, 3013, 3014, 3015, 3015, 3016, 3018, 3014, - 3017, 3019, 3022, 3012, 3026, 3017, 3011, 3023, 3024, 3025, - 3025, 3024, 3027, 3013, 3028, 3028, 3029, 3016, 3018, 3026, - 3019, 3030, 3022, 3033, 3031, 3023, 3034, 3029, 3031, 3035, - - 3027, 3037, 3037, 3036, 3038, 3035, 3030, 3036, 3033, 3040, - 3041, 3034, 3042, 3043, 3043, 3044, 3046, 3038, 3045, 3047, - 3048, 3051, 3040, 3041, 3049, 3045, 3061, 3042, 3044, 3044, - 3050, 3061, 3047, 3054, 3046, 3052, 3052, 3055, 3050, 3059, - 3048, 3051, 3065, 3049, 3056, 3054, 3055, 3062, 3056, 3057, - 3057, 3058, 3058, 3060, 3060, 3063, 3062, 3064, 3059, 3066, - 3066, 3068, 3065, 3072, 3072, 3073, 3074, 3075, 3075, 3064, - 3076, 3063, 3077, 3078, 3073, 3079, 3082, 3082, 3080, 3083, - 3081, 3084, 3068, 3076, 3079, 3077, 3078, 3080, 3074, 3081, - 3086, 3086, 3089, 3091, 3092, 3093, 3084, 3089, 3091, 3083, - - 3093, 3094, 3095, 3096, 3099, 3097, 3101, 3103, 3092, 3094, - 3102, 3101, 3096, 3097, 3107, 3102, 3104, 3104, 3109, 3099, - 3106, 3095, 3103, 3105, 3105, 3106, 3108, 3110, 3110, 3107, - 3112, 3108, 3111, 3113, 3114, 3112, 3115, 3109, 3116, 3111, - 3117, 3118, 3115, 3116, 3121, 3117, 3120, 3120, 3122, 3123, - 3123, 3113, 3114, 3122, 3128, 3118, 3124, 3124, 3127, 3121, - 3129, 3130, 3130, 3127, 3132, 3131, 3133, 3128, 3131, 3132, - 3132, 3133, 3134, 3135, 3129, 3136, 3137, 3134, 3138, 3139, - 3137, 3136, 3140, 3138, 3139, 3141, 3142, 3135, 3143, 3144, - 3145, 3140, 3146, 3147, 3142, 3144, 3145, 3146, 3148, 3148, - - 3141, 3150, 3151, 3152, 3154, 3147, 3152, 3151, 3150, 3143, - 3156, 3159, 3157, 3158, 3160, 3156, 3154, 3157, 3158, 3161, - 3166, 3162, 3163, 3163, 3164, 3170, 3166, 3160, 3161, 3159, - 3162, 3165, 3167, 3164, 3171, 3165, 3172, 3167, 3175, 3176, - 3171, 3177, 3172, 3170, 3178, 3179, 3179, 3180, 3181, 3183, - 3186, 3184, 3185, 3185, 3180, 3187, 3188, 3175, 3183, 3176, - 3184, 3177, 3190, 3178, 3187, 3186, 3194, 3181, 3189, 3189, - 3192, 3188, 3196, 3197, 3197, 3198, 3196, 3199, 3200, 3202, - 0, 3190, 3204, 3199, 3200, 3192, 3194, 3203, 3204, 3205, - 3205, 3206, 3207, 3210, 3211, 3216, 3208, 3213, 3202, 3206, - - 3198, 3208, 3210, 3213, 3215, 3203, 3214, 3211, 3215, 3214, - 3217, 3218, 3218, 3216, 3219, 3221, 3221, 3207, 3222, 3224, - 3223, 3226, 3227, 3222, 3217, 3223, 3228, 3229, 3230, 3219, - 3231, 3231, 3232, 3230, 3226, 3228, 3227, 3224, 3233, 3233, - 3234, 3234, 3236, 3236, 3237, 3238, 3243, 3239, 3237, 3229, - 3238, 3241, 3241, 3244, 3246, 3232, 3239, 3245, 3244, 3246, - 3246, 3247, 3249, 3250, 3251, 0, 3243, 3252, 3252, 3245, - 3254, 3254, 3258, 3247, 3255, 3255, 3256, 3256, 3257, 3259, - 3262, 3257, 3249, 3250, 3251, 3258, 3261, 3261, 3264, 3265, - 3265, 3268, 3259, 3266, 3266, 3267, 3267, 3270, 3262, 3269, - - 3269, 3271, 3272, 3273, 3274, 3274, 3268, 3275, 3264, 3273, - 3270, 3275, 3278, 3284, 3285, 3280, 3272, 3278, 3278, 3271, - 3279, 3280, 3281, 3279, 3283, 3286, 3287, 3281, 3291, 3283, - 3283, 3288, 3287, 3289, 3285, 3290, 3284, 3288, 3292, 3289, - 3303, 3290, 3292, 3293, 3293, 3286, 3296, 3296, 3298, 3297, - 3300, 3305, 3305, 3291, 3297, 3298, 3301, 3304, 3300, 3301, - 3304, 3306, 3307, 3308, 3310, 3303, 3311, 3307, 3309, 3309, - 3312, 3312, 3313, 3315, 3314, 3316, 3321, 3314, 3306, 3306, - 3311, 3308, 3317, 3319, 3310, 3314, 3313, 3315, 3319, 3319, - 3317, 3320, 3322, 3322, 3316, 3321, 3320, 3320, 3323, 3323, - - 3324, 3324, 3325, 3325, 3326, 3326, 3327, 3327, 3328, 3329, - 3330, 3331, 3332, 3333, 3329, 3334, 3336, 3335, 3337, 3338, - 3333, 3332, 3335, 3337, 3328, 3339, 3340, 3341, 3338, 3334, - 3330, 3343, 3343, 3344, 3344, 3336, 3345, 3331, 3346, 3345, - 3347, 3347, 3348, 3350, 3349, 3339, 3340, 3341, 3348, 3349, - 3352, 3352, 3353, 3346, 3354, 3354, 3358, 3355, 3359, 3353, - 3364, 3350, 3355, 3357, 3357, 3358, 3361, 3359, 3360, 3360, - 3362, 3365, 3365, 3366, 3366, 3361, 3367, 3368, 3364, 3362, - 3367, 3369, 3370, 3371, 3372, 3373, 3368, 3376, 3375, 3476, - 3373, 3373, 3377, 3370, 3378, 3379, 3376, 3476, 3371, 3379, - - 3369, 3375, 3380, 3380, 3372, 3381, 3384, 3377, 3382, 3378, - 3381, 3382, 3383, 3386, 3390, 3391, 3391, 3383, 3392, 3390, - 3395, 3384, 3394, 3394, 3396, 3397, 3399, 3399, 3386, 3400, - 3400, 3401, 3392, 3402, 3395, 3403, 3407, 3408, 3411, 3402, - 3401, 3409, 3408, 3397, 3414, 3412, 3416, 3403, 3418, 3396, - 3409, 3412, 3419, 3418, 3420, 3420, 3414, 3419, 3411, 3421, - 3423, 3407, 3424, 3426, 3427, 3423, 3428, 3416, 3421, 3429, - 3429, 3431, 3431, 3429, 3426, 3434, 3424, 3427, 3432, 3432, - 3428, 3433, 3433, 3435, 3434, 3436, 3439, 3437, 3438, 3442, - 3447, 3439, 3443, 3443, 3444, 3442, 3445, 3446, 3446, 3444, - - 3448, 3445, 3449, 3435, 3450, 3436, 3437, 3438, 3447, 3450, - 3451, 3452, 3448, 3454, 3455, 3455, 3457, 3452, 3461, 3458, - 3457, 3459, 3469, 3449, 3458, 3462, 3459, 3463, 3451, 3460, - 3460, 3465, 3467, 3467, 3470, 3469, 3471, 3461, 3454, 3472, - 3462, 3473, 3463, 3472, 3474, 3475, 3478, 3470, 3477, 3471, - 3473, 3465, 3480, 3477, 3482, 3479, 3481, 3481, 3483, 3484, - 3474, 3485, 3485, 3482, 3475, 3487, 3478, 3479, 3486, 3486, - 3497, 3493, 3480, 3490, 3491, 0, 3483, 3493, 3490, 3490, - 3494, 3494, 3495, 3495, 3487, 3484, 3499, 3499, 3491, 3501, - 3502, 3497, 3504, 3505, 3506, 3509, 3509, 3504, 3510, 3506, - - 3513, 3511, 3512, 3514, 3514, 3501, 3502, 3515, 3512, 3505, - 3511, 3517, 3517, 3518, 3519, 3520, 3522, 3523, 3510, 3521, - 3523, 3524, 3524, 3513, 3525, 3526, 3515, 3518, 3530, 3527, - 3522, 3528, 3528, 3532, 3530, 3519, 3520, 3533, 3521, 3534, - 3537, 3538, 3525, 3533, 3534, 3541, 3526, 3527, 3539, 3539, - 3540, 3540, 3542, 3532, 3543, 3543, 3545, 3544, 3546, 3549, - 3541, 3548, 3537, 3547, 3550, 3545, 3554, 3538, 3544, 3547, - 3555, 3549, 3542, 3555, 3543, 3551, 3551, 3552, 3546, 3561, - 3548, 3554, 3552, 3562, 3550, 3553, 3553, 3556, 3557, 3557, - 3556, 3561, 3563, 3564, 3565, 3566, 3566, 3570, 3564, 3567, - - 3565, 3569, 3567, 3562, 3572, 3573, 3573, 3569, 3574, 3572, - 3575, 3576, 3563, 3574, 3577, 3570, 3580, 3576, 3578, 3578, - 3581, 3582, 3583, 3584, 3584, 3585, 3586, 3587, 3580, 3575, - 3601, 3577, 3577, 3589, 3589, 3583, 3587, 3593, 3581, 3590, - 3590, 3599, 3586, 3601, 3585, 3592, 3582, 3591, 3591, 3594, - 3592, 3593, 3595, 3595, 3594, 3596, 3596, 3597, 3597, 3598, - 3600, 3600, 3599, 3602, 3603, 3608, 3604, 3614, 3598, 3616, - 3603, 3604, 3607, 3607, 3610, 3610, 3611, 3611, 3617, 3618, - 3619, 3608, 3620, 3620, 3622, 3622, 3614, 3623, 3624, 3602, - 3625, 3616, 3627, 0, 3628, 3629, 3629, 3630, 3618, 3631, - - 3617, 3634, 3619, 3628, 3625, 3632, 3632, 3624, 3635, 3636, - 3633, 3637, 3627, 3623, 3633, 3636, 3640, 3630, 3638, 3631, - 3635, 3634, 3638, 3641, 3642, 3644, 3643, 3645, 3648, 3641, - 3644, 3637, 3645, 3653, 3640, 3649, 3649, 3651, 3651, 3655, - 3660, 3652, 3654, 3664, 3642, 3643, 3652, 3653, 3654, 3648, - 3656, 3655, 3657, 3657, 3658, 3665, 3667, 3662, 3656, 3658, - 3660, 3662, 3663, 3664, 3666, 3668, 3669, 3663, 3667, 3666, - 3670, 3672, 3673, 3674, 3675, 3665, 3670, 3668, 3677, 3672, - 3680, 3678, 3679, 3681, 3669, 3683, 3684, 3686, 3681, 3685, - 3683, 3673, 3686, 3674, 3675, 3685, 3677, 3678, 3688, 3679, - - 3679, 3680, 3689, 3690, 3700, 3689, 3684, 3694, 3694, 3695, - 3695, 3696, 3701, 3703, 3703, 3696, 3690, 3701, 3688, 3700, - 3704, 3705, 3706, 3706, 3708, 3704, 3711, 3711, 3712, 3712, - 3716, 3712, 3713, 3713, 3716, 3713, 3714, 3714, 3718, 3708, - 3705, 3715, 3715, 3718, 3715, 3719, 3720, 3720, 3721, 3722, - 3724, 3724, 3725, 3725, 3719, 3727, 3728, 3730, 3729, 3731, - 3731, 3727, 3728, 3722, 3729, 3730, 3721, 3732, 3732, 3733, - 3733, 3734, 3735, 3730, 3736, 3737, 3737, 3738, 3739, 3736, - 3742, 3743, 3744, 3748, 3745, 3746, 3744, 3749, 3743, 3749, - 0, 3734, 3735, 3745, 3750, 3738, 3751, 3751, 3739, 3750, - - 3746, 3748, 3752, 3753, 3753, 3742, 3754, 3754, 3755, 3755, - 3757, 3752, 3756, 3756, 3758, 3759, 3760, 3761, 3762, 3763, - 3759, 3764, 3761, 3761, 3762, 3760, 3765, 3768, 3760, 3758, - 3766, 3770, 3757, 3767, 0, 3766, 3764, 3770, 3767, 3769, - 3769, 3774, 3771, 3779, 3763, 3796, 3768, 3765, 3771, 3772, - 3772, 3773, 3773, 3775, 3778, 3778, 3774, 3779, 3775, 3780, - 3780, 3782, 3782, 3783, 3785, 3787, 3787, 3788, 3788, 3789, - 3789, 3796, 3783, 3790, 3790, 3792, 3792, 3793, 3793, 3794, - 3794, 3798, 3785, 3795, 3795, 3799, 3799, 3802, 3803, 3804, - 3798, 3805, 3810, 3804, 3806, 3806, 3809, 3809, 3811, 3812, - - 3814, 3810, 3815, 3815, 3816, 3818, 3805, 3802, 3803, 3806, - 3811, 3817, 3817, 3819, 3825, 3814, 3820, 3821, 3821, 3812, - 3818, 3822, 3830, 3816, 3823, 3823, 3819, 3830, 3820, 3825, - 3826, 3826, 3831, 3822, 3832, 3833, 3835, 3832, 3834, 3834, - 3837, 3838, 3839, 3837, 3840, 3841, 3843, 3838, 3842, 3840, - 3831, 3845, 3855, 3850, 3835, 3849, 3839, 3845, 3846, 3849, - 3856, 3833, 3843, 0, 3841, 3868, 3842, 3846, 3850, 3852, - 3852, 3865, 3866, 3869, 3868, 3866, 3865, 3870, 3855, 3870, - 3856, 3871, 3869, 3872, 3875, 3882, 3873, 3876, 3876, 3877, - 3877, 3878, 3878, 3880, 3880, 3884, 3883, 3875, 3885, 3884, - - 3871, 3886, 3872, 3872, 3873, 3883, 3888, 3890, 3882, 3891, - 3892, 3895, 3893, 3890, 3896, 3896, 3886, 3893, 3885, 3898, - 3888, 3892, 3894, 3897, 3894, 3899, 3895, 3901, 3900, 3904, - 3902, 3903, 3891, 3906, 3905, 3907, 3897, 3908, 3898, 3905, - 3903, 3904, 3908, 3899, 3900, 3902, 3909, 3907, 3910, 3910, - 3911, 3912, 3901, 3913, 3906, 3914, 3914, 3915, 3919, 3916, - 3917, 3918, 3924, 3919, 3912, 3909, 3913, 3925, 3917, 0, - 3911, 3926, 3926, 3927, 3929, 3929, 3924, 3915, 3916, 3930, - 3928, 3918, 3927, 3928, 3930, 3931, 3931, 3925, 3932, 3932, - 3933, 3933, 3934, 3935, 3936, 3937, 3938, 3936, 3939, 3940, - - 3937, 3938, 3941, 3942, 3943, 3944, 3945, 3945, 3941, 3946, - 3944, 3934, 0, 3935, 3940, 3956, 3943, 3942, 3947, 3947, - 3948, 3948, 3960, 3939, 3949, 3949, 3951, 3951, 3952, 3946, - 3953, 3955, 3955, 3952, 3959, 3953, 3957, 3957, 3956, 3958, - 3958, 3960, 3961, 3961, 3963, 3964, 3966, 3967, 3973, 3959, - 3970, 3970, 3971, 3971, 3972, 3974, 3964, 3975, 3976, 3963, - 3977, 3974, 3972, 3975, 3978, 3967, 3979, 3973, 3980, 3980, - 3966, 3979, 3976, 3977, 3982, 3982, 3987, 3988, 3990, 3993, - 3996, 3994, 3998, 3978, 3997, 3997, 3999, 4001, 0, 4003, - 3999, 3987, 3988, 3990, 3996, 4006, 4004, 4002, 3998, 4005, - - 3993, 3994, 4002, 4009, 4009, 4007, 4008, 4001, 4003, 4004, - 4007, 4008, 4005, 4012, 4006, 4013, 4019, 4014, 4015, 4016, - 4017, 4020, 4020, 4021, 4022, 4019, 4023, 4023, 4021, 4027, - 4022, 4030, 4031, 0, 4012, 4014, 4013, 4016, 4015, 4017, - 4024, 4025, 4026, 4028, 4036, 4024, 4025, 4026, 4027, 4028, - 4032, 4030, 4031, 4034, 4032, 4033, 4033, 4038, 4034, 4035, - 4035, 4038, 4036, 4039, 4040, 4041, 4042, 4043, 4044, 0, - 4045, 4040, 0, 4043, 4046, 4046, 4047, 4047, 4048, 4048, - 4050, 4050, 4039, 4045, 4041, 4042, 4052, 4044, 4053, 4053, - 4054, 4052, 4055, 4056, 4057, 4058, 4064, 4055, 4060, 4054, - - 4059, 4059, 4054, 4060, 4067, 4069, 4065, 4074, 4058, 4064, - 4065, 0, 4056, 4057, 4068, 4068, 4070, 4070, 4071, 4071, - 4072, 4073, 4075, 4075, 4069, 4072, 4074, 0, 4073, 4077, - 4067, 4076, 4076, 4078, 4077, 4078, 4079, 4079, 4080, 4081, - 4082, 4084, 4083, 4087, 4087, 4080, 4081, 4083, 4088, 4090, - 4091, 4092, 4093, 4097, 4090, 4091, 4094, 4094, 4098, 4082, - 4084, 4096, 4096, 4099, 4099, 4100, 4100, 4088, 4101, 4105, - 4092, 4093, 4097, 4103, 4103, 4101, 4105, 4098, 4104, 4104, - 4107, 4110, 4111, 4112, 0, 4107, 4110, 4113, 4113, 4114, - 4114, 0, 0, 0, 0, 0, 0, 0, 0, 0, - - 0, 4111, 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 + 417, 421, 419, 409, 424, 427, 429, 409, 409, 409, + 409, 409, 428, 169, 409, 422, 423, 409, 424, 421, + 425, 429, 426, 430, 431, 427, 425, 426, 430, 431, + 425, 432, 428, 433, 434, 434, 435, 436, 438, 433, + 437, 439, 440, 441, 445, 426, 432, 446, 440, 436, + 443, 449, 438, 447, 448, 443, 435, 451, 437, 439, + 444, 444, 451, 444, 445, 449, 456, 446, 441, 447, + 448, 450, 452, 450, 452, 452, 453, 454, 455, 455, + 453, 454, 457, 458, 459, 456, 460, 463, 469, 464, + + 466, 474, 452, 463, 466, 461, 454, 457, 464, 458, + 460, 465, 459, 461, 461, 467, 465, 468, 471, 469, + 470, 474, 471, 468, 467, 461, 470, 461, 462, 472, + 473, 476, 472, 462, 478, 473, 475, 475, 477, 477, + 485, 462, 462, 479, 476, 462, 462, 480, 479, 462, + 481, 481, 482, 478, 483, 485, 486, 484, 482, 483, + 480, 484, 487, 488, 489, 489, 490, 487, 488, 491, + 492, 493, 489, 489, 495, 496, 494, 486, 490, 494, + 497, 499, 498, 493, 504, 497, 495, 498, 492, 491, + 500, 501, 502, 502, 500, 503, 496, 505, 505, 499, + + 503, 506, 508, 501, 511, 504, 509, 509, 508, 512, + 513, 514, 515, 516, 517, 518, 522, 512, 516, 520, + 514, 524, 521, 506, 523, 511, 525, 518, 526, 527, + 523, 513, 525, 515, 517, 524, 522, 520, 527, 520, + 521, 529, 528, 530, 526, 531, 529, 526, 528, 532, + 533, 534, 532, 531, 535, 536, 531, 530, 537, 538, + 540, 536, 538, 535, 533, 539, 534, 541, 542, 544, + 543, 539, 541, 544, 540, 545, 546, 548, 537, 547, + 549, 546, 548, 550, 551, 554, 555, 558, 167, 539, + 542, 543, 545, 556, 547, 557, 549, 551, 560, 557, + + 573, 573, 550, 552, 552, 554, 558, 555, 556, 552, + 559, 552, 561, 563, 560, 559, 561, 552, 565, 552, + 564, 562, 552, 552, 566, 564, 562, 568, 563, 552, + 562, 563, 567, 566, 565, 569, 570, 565, 567, 570, + 571, 572, 568, 567, 574, 564, 575, 575, 577, 576, + 579, 569, 578, 578, 580, 580, 581, 582, 586, 584, + 577, 572, 583, 571, 576, 579, 587, 583, 584, 574, + 585, 585, 588, 590, 591, 581, 592, 586, 588, 582, + 592, 587, 593, 591, 594, 590, 593, 595, 596, 597, + 594, 598, 599, 601, 600, 605, 602, 603, 599, 595, + + 602, 608, 604, 596, 604, 598, 606, 608, 597, 600, + 603, 601, 607, 607, 606, 609, 610, 611, 612, 605, + 614, 613, 610, 611, 613, 615, 616, 609, 617, 619, + 612, 616, 617, 618, 614, 620, 618, 621, 165, 623, + 615, 624, 624, 622, 620, 625, 625, 619, 622, 622, + 627, 620, 623, 621, 620, 626, 627, 626, 628, 628, + 629, 629, 630, 632, 631, 633, 634, 636, 630, 631, + 631, 635, 636, 637, 635, 638, 639, 640, 634, 639, + 641, 632, 640, 638, 643, 642, 633, 644, 643, 645, + 646, 648, 637, 644, 646, 647, 648, 649, 650, 650, + + 651, 652, 653, 641, 642, 654, 657, 653, 656, 645, + 655, 649, 657, 647, 658, 651, 659, 661, 663, 658, + 662, 662, 652, 664, 654, 737, 655, 737, 656, 660, + 659, 667, 660, 665, 668, 661, 663, 660, 665, 664, + 660, 660, 666, 670, 671, 667, 670, 666, 672, 668, + 671, 673, 674, 675, 673, 676, 674, 672, 677, 678, + 676, 677, 680, 679, 678, 682, 681, 685, 683, 684, + 686, 686, 675, 681, 684, 687, 688, 689, 674, 679, + 680, 683, 691, 682, 687, 690, 692, 685, 693, 693, + 690, 694, 689, 695, 696, 688, 703, 701, 697, 698, + + 692, 703, 695, 691, 697, 698, 696, 694, 699, 700, + 700, 699, 700, 701, 702, 704, 705, 702, 706, 707, + 708, 709, 713, 710, 707, 711, 712, 709, 710, 712, + 705, 711, 706, 704, 715, 714, 716, 718, 717, 708, + 714, 716, 716, 720, 719, 723, 724, 713, 722, 86, + 715, 717, 718, 719, 722, 724, 720, 721, 725, 726, + 721, 728, 721, 725, 723, 727, 727, 729, 728, 721, + 730, 732, 731, 730, 729, 721, 721, 721, 731, 726, + 733, 734, 736, 732, 738, 733, 734, 734, 730, 735, + 735, 739, 740, 739, 741, 733, 742, 743, 744, 745, + + 746, 747, 748, 738, 751, 747, 746, 736, 749, 750, + 752, 748, 741, 740, 742, 743, 754, 744, 753, 745, + 755, 753, 751, 749, 750, 756, 755, 757, 758, 752, + 753, 754, 759, 760, 761, 762, 764, 763, 765, 762, + 758, 757, 766, 767, 768, 756, 769, 772, 772, 775, + 81, 759, 764, 761, 760, 763, 765, 766, 771, 770, + 774, 767, 767, 768, 770, 769, 773, 776, 775, 777, + 773, 778, 771, 779, 774, 780, 778, 781, 776, 782, + 783, 784, 786, 777, 785, 783, 782, 787, 788, 779, + 781, 785, 787, 788, 780, 789, 790, 791, 792, 794, + + 784, 793, 795, 790, 796, 798, 786, 792, 794, 791, + 798, 795, 797, 789, 799, 793, 796, 799, 797, 800, + 801, 802, 803, 800, 804, 805, 806, 804, 807, 807, + 802, 808, 808, 810, 801, 811, 809, 803, 810, 805, + 808, 809, 809, 813, 811, 814, 815, 806, 816, 817, + 819, 814, 818, 817, 820, 821, 824, 822, 823, 826, + 825, 821, 813, 822, 818, 815, 823, 825, 816, 827, + 828, 824, 820, 831, 835, 819, 834, 826, 838, 834, + 839, 841, 844, 842, 843, 76, 839, 838, 831, 842, + 828, 835, 845, 843, 827, 829, 845, 829, 844, 848, + + 829, 846, 846, 841, 829, 847, 847, 829, 849, 850, + 848, 851, 852, 75, 829, 829, 855, 829, 852, 857, + 854, 855, 856, 850, 858, 859, 849, 862, 858, 865, + 861, 851, 853, 853, 853, 861, 853, 857, 860, 853, + 854, 864, 860, 856, 853, 866, 862, 863, 866, 859, + 853, 853, 863, 853, 865, 867, 864, 868, 860, 870, + 867, 867, 869, 869, 868, 871, 872, 872, 873, 874, + 871, 875, 874, 873, 870, 878, 875, 876, 876, 877, + 879, 877, 880, 881, 882, 884, 880, 878, 883, 885, + 885, 886, 887, 884, 888, 889, 889, 890, 891, 879, + + 892, 881, 69, 893, 882, 904, 886, 883, 888, 893, + 891, 894, 887, 895, 902, 890, 894, 903, 895, 896, + 896, 897, 892, 899, 900, 904, 897, 897, 899, 901, + 900, 901, 902, 905, 906, 908, 903, 907, 910, 914, + 906, 908, 907, 909, 910, 911, 909, 905, 912, 912, + 913, 913, 915, 911, 916, 918, 917, 914, 919, 918, + 915, 917, 920, 921, 922, 919, 923, 923, 924, 927, + 925, 928, 916, 926, 926, 927, 929, 924, 925, 921, + 920, 931, 932, 922, 933, 934, 935, 936, 937, 928, + 931, 938, 939, 940, 934, 929, 938, 939, 943, 944, + + 932, 935, 940, 937, 941, 945, 946, 941, 942, 948, + 933, 936, 943, 942, 945, 947, 949, 949, 950, 946, + 947, 947, 951, 948, 944, 952, 953, 954, 955, 963, + 957, 955, 957, 950, 952, 958, 958, 959, 960, 955, + 961, 951, 962, 960, 964, 954, 965, 962, 967, 963, + 953, 966, 968, 975, 970, 969, 972, 967, 959, 969, + 971, 961, 972, 976, 964, 973, 974, 977, 965, 975, + 978, 966, 970, 980, 973, 968, 978, 979, 974, 971, + 983, 977, 976, 981, 984, 979, 985, 980, 981, 982, + 982, 986, 987, 988, 989, 985, 990, 991, 1502, 983, + + 987, 992, 993, 994, 984, 996, 995, 999, 1502, 994, + 998, 986, 995, 988, 989, 1003, 991, 997, 990, 996, + 1000, 992, 993, 997, 998, 1001, 1000, 999, 1002, 1004, + 1005, 1001, 1002, 1006, 1003, 1005, 1007, 1007, 1008, 1009, + 1011, 1004, 1010, 1011, 1012, 1009, 1008, 1013, 1010, 1004, + 1014, 1016, 1015, 1019, 1006, 1018, 1014, 1017, 1017, 1020, + 1013, 1015, 1012, 1023, 1020, 1021, 1019, 1026, 1021, 1022, + 1027, 1016, 1024, 1018, 1022, 1022, 1024, 1028, 1023, 1025, + 1025, 1021, 1029, 1021, 1030, 1032, 1033, 1029, 1034, 1026, + 1027, 1034, 1028, 1036, 1037, 1038, 1040, 1041, 1041, 1045, + + 1033, 1040, 1034, 1030, 1042, 1049, 1036, 1050, 1042, 1032, + 1043, 1044, 1044, 1051, 1037, 1047, 1038, 1039, 1051, 1048, + 1039, 1050, 1039, 1049, 1045, 1043, 1039, 1046, 1039, 1052, + 1054, 1046, 1046, 1039, 1048, 1047, 1053, 1055, 1039, 1054, + 1056, 1053, 1053, 1052, 1056, 1057, 1059, 1058, 1058, 1060, + 1061, 1055, 1058, 1063, 1060, 1064, 1056, 1067, 1059, 1065, + 1057, 64, 1058, 1067, 1061, 1062, 1062, 1066, 1065, 1064, + 1068, 1069, 1066, 1070, 1063, 1068, 1073, 1069, 1072, 1070, + 1071, 1071, 1073, 1072, 1074, 1075, 1078, 1076, 1079, 1080, + 1081, 1082, 1082, 1079, 1083, 1086, 1085, 1088, 1078, 1083, + + 1087, 1084, 1081, 1080, 1075, 1076, 1074, 1077, 1077, 1084, + 1085, 1086, 1089, 1077, 1087, 1077, 1088, 1091, 1090, 1092, + 1093, 1077, 1094, 1091, 1092, 1095, 1077, 1077, 1096, 1097, + 1100, 1089, 1093, 1077, 1090, 1098, 1098, 1102, 1099, 1104, + 1094, 1095, 1099, 1102, 1105, 1103, 1096, 1097, 1103, 1105, + 1100, 1106, 1108, 1107, 1109, 1113, 1111, 1108, 1104, 1107, + 1112, 1114, 1115, 1116, 1106, 1111, 1117, 1114, 1119, 1112, + 1118, 1113, 1116, 1109, 1122, 1118, 1120, 1121, 1121, 1123, + 1124, 1126, 1127, 1115, 1125, 1117, 1129, 1126, 1119, 1124, + 1120, 1123, 1129, 1125, 1122, 1128, 1128, 1131, 1133, 1127, + + 1134, 1135, 1135, 1136, 1137, 1138, 1139, 1140, 1141, 1137, + 1170, 1138, 1133, 1131, 1142, 1143, 1144, 1170, 1145, 1148, + 1134, 1144, 1141, 1145, 1148, 1139, 1140, 1150, 1136, 1149, + 1143, 1154, 1142, 1152, 1149, 1153, 1150, 1151, 1151, 1152, + 1154, 1153, 1155, 1156, 1158, 1159, 1162, 59, 1161, 1161, + 1159, 1159, 1161, 1164, 1165, 1163, 1156, 1155, 1163, 1166, + 1158, 1162, 1167, 1168, 1166, 1169, 1173, 1164, 1171, 1172, + 1174, 1176, 1175, 1178, 1165, 1184, 1168, 1168, 1175, 1173, + 1177, 1169, 1167, 1180, 1171, 1174, 1177, 1172, 1178, 1179, + 1187, 1176, 1182, 1182, 1179, 1183, 1184, 1180, 1183, 1185, + + 1186, 1188, 1189, 1190, 1185, 1186, 1187, 1189, 1190, 1191, + 1188, 1193, 1194, 1195, 1196, 1200, 1197, 1193, 1199, 1195, + 1203, 1191, 1197, 1198, 1198, 1204, 1201, 1199, 1194, 1201, + 1202, 1202, 1205, 1200, 1206, 1196, 1207, 1206, 1203, 1208, + 1209, 1210, 1219, 1211, 1204, 1208, 1209, 1210, 1211, 1207, + 1212, 1213, 1205, 1214, 1215, 1212, 1217, 1213, 1214, 1218, + 1215, 1217, 1219, 1220, 1223, 1221, 1222, 1222, 1226, 1220, + 1221, 1224, 1225, 1226, 1227, 1228, 1231, 1218, 1233, 1223, + 1224, 1225, 1229, 1230, 1232, 1229, 1230, 1231, 1234, 1232, + 1235, 1236, 1227, 1237, 1228, 1238, 1233, 1236, 1239, 1237, + + 1234, 1240, 1240, 1239, 1241, 1242, 1243, 1245, 1244, 1235, + 1238, 1246, 1243, 1247, 1249, 1246, 1251, 1248, 1250, 1242, + 1244, 1253, 1250, 1241, 1256, 1245, 1248, 1254, 1255, 1255, + 1257, 1247, 1256, 1249, 1258, 1257, 1254, 1259, 1261, 1258, + 1253, 1251, 1263, 1262, 1264, 1266, 1265, 1267, 1267, 1264, + 1268, 1272, 1261, 1269, 1263, 1265, 1270, 1259, 1262, 1269, + 1266, 1271, 1270, 1273, 1277, 1281, 1272, 1274, 1278, 1271, + 1268, 1275, 1274, 1275, 1280, 1276, 1279, 1285, 1277, 1273, + 1276, 1279, 1278, 1282, 1281, 1283, 1282, 1284, 1290, 1280, + 1287, 1287, 1283, 1288, 1289, 1291, 1285, 1290, 1289, 1292, + + 1293, 1295, 1284, 1294, 1298, 1292, 1296, 1288, 1298, 1294, + 58, 1296, 1307, 1291, 1300, 1293, 1299, 1299, 1303, 1300, + 1296, 1295, 1296, 1301, 1301, 1296, 1302, 1304, 1306, 1305, + 1307, 1303, 1305, 1302, 1308, 1310, 1311, 1312, 1313, 1315, + 1310, 1304, 1317, 1308, 1313, 1314, 1316, 1306, 1322, 1312, + 1314, 1319, 1319, 1315, 1320, 1311, 1326, 1316, 1321, 1320, + 1323, 1317, 1324, 1321, 1325, 1323, 1324, 1327, 1322, 1328, + 1330, 1326, 1329, 1325, 1331, 1329, 1333, 1332, 1334, 1335, + 1336, 1331, 1327, 1337, 1329, 1330, 1336, 1339, 1328, 1332, + 1338, 1340, 1343, 1339, 1341, 1333, 1342, 1335, 1337, 1334, + + 1344, 1338, 1346, 1345, 1347, 1342, 1350, 1343, 1348, 1357, + 1349, 1340, 1338, 1353, 1341, 1345, 1349, 1354, 1352, 1344, + 1356, 1346, 1355, 1348, 1352, 1357, 1350, 1358, 1353, 1347, + 1355, 1354, 1358, 1359, 1361, 1362, 1360, 1363, 1364, 1364, + 1356, 1360, 1360, 1367, 1366, 1359, 1366, 1372, 1368, 1362, + 1363, 1372, 1369, 1361, 1365, 1365, 1367, 1368, 1369, 1365, + 1370, 1370, 1365, 1365, 1371, 1373, 1374, 1365, 1378, 1371, + 1375, 1376, 1374, 1365, 1373, 1375, 1376, 1365, 1377, 1377, + 1379, 1380, 1380, 1381, 1379, 1382, 1381, 1384, 1381, 1378, + 1380, 1383, 1385, 1387, 1386, 1388, 1387, 1389, 1385, 1384, + + 1386, 1388, 1390, 1391, 1392, 1382, 1389, 1393, 1391, 1383, + 1394, 1395, 53, 1396, 1402, 1397, 1394, 1395, 1392, 1396, + 1397, 1399, 1390, 1398, 1400, 1393, 1401, 1398, 1402, 1403, + 1403, 1401, 1405, 1400, 1399, 1408, 1404, 1404, 1400, 1404, + 1400, 1407, 1400, 1405, 1400, 1407, 1409, 1410, 1411, 1415, + 1408, 1412, 1412, 1413, 1413, 1414, 1416, 1411, 1417, 1418, + 1414, 1414, 1415, 1419, 1420, 1410, 1409, 1417, 1418, 1421, + 1416, 1422, 1423, 1424, 1421, 1419, 1425, 1426, 1427, 1428, + 1428, 1423, 1429, 1431, 1427, 1422, 1420, 1433, 1430, 1437, + 1434, 1426, 1424, 1432, 1429, 1425, 1430, 1431, 1432, 1434, + + 1435, 1433, 1436, 1438, 1439, 1439, 1440, 1435, 1438, 1441, + 1441, 1442, 1446, 1443, 1437, 1443, 1442, 1446, 1447, 1445, + 1436, 1440, 1445, 1448, 1449, 1449, 1450, 1451, 1451, 1452, + 1452, 1453, 1448, 1454, 1455, 1456, 1453, 1447, 1457, 1457, + 1458, 1459, 1460, 1461, 1462, 1460, 1450, 1463, 1464, 1465, + 1462, 1465, 1463, 1466, 1454, 1455, 1456, 1464, 1459, 1468, + 1458, 1469, 1468, 1461, 1469, 1470, 1471, 1472, 1473, 1474, + 1475, 1466, 1472, 1481, 1474, 1543, 1476, 1543, 1475, 1471, + 1470, 1476, 1473, 1477, 1478, 1480, 1477, 1479, 1479, 1478, + 1480, 1481, 1482, 1483, 1484, 1486, 1487, 1493, 1482, 1501, + + 1483, 1486, 1487, 1488, 1488, 1489, 1490, 1484, 1491, 1492, + 1489, 1490, 1494, 1497, 1491, 1498, 1493, 1501, 1492, 1495, + 1495, 1496, 1496, 1494, 1500, 1503, 1504, 1505, 1506, 1500, + 1507, 1508, 1509, 1497, 1506, 1498, 1507, 1508, 1511, 1512, + 1503, 1513, 1514, 1509, 1511, 1515, 1504, 1514, 1516, 1518, + 1505, 1515, 1517, 1512, 1519, 1513, 1520, 1520, 1521, 1512, + 1522, 1513, 1523, 1518, 1517, 1524, 1525, 1527, 1516, 1530, + 1524, 1528, 1519, 1526, 1526, 1531, 1528, 1533, 1521, 1532, + 1523, 1534, 1533, 1533, 1525, 1522, 1535, 1536, 1530, 1531, + 1527, 1538, 1532, 1537, 1539, 1540, 1536, 1549, 1541, 1534, + + 1544, 1537, 1542, 1541, 1535, 1538, 1541, 1547, 1549, 1539, + 1540, 1542, 1546, 1540, 1544, 1548, 1550, 1551, 1546, 1548, + 1552, 1550, 1550, 1547, 1553, 1554, 1555, 1556, 1558, 1557, + 1554, 1555, 1556, 1559, 1560, 1562, 1551, 1563, 1559, 1564, + 1565, 1565, 1553, 1567, 1568, 1569, 1552, 1557, 1558, 1562, + 1570, 1569, 1566, 1571, 1560, 1563, 1566, 1564, 1572, 1573, + 1574, 1567, 1570, 1568, 1575, 1576, 1577, 1578, 1580, 1571, + 1583, 1577, 48, 1573, 1578, 1574, 1579, 1572, 1581, 1575, + 1582, 1579, 1585, 1585, 1576, 1582, 1580, 1584, 1586, 1587, + 1588, 1583, 1581, 1589, 1589, 1590, 1584, 1592, 1587, 1591, + + 1596, 1590, 1597, 1586, 18, 1591, 1593, 1593, 1594, 1594, + 1588, 1592, 1595, 1606, 1598, 1599, 1596, 1606, 1595, 1598, + 1600, 1599, 1601, 1597, 1602, 1602, 1600, 1607, 1601, 1603, + 1603, 1605, 1605, 1609, 1608, 1611, 1607, 1612, 1614, 1610, + 1613, 1613, 1616, 1618, 1612, 1609, 1615, 1619, 1616, 1603, + 1611, 1603, 1608, 1610, 1615, 1617, 1620, 1618, 1614, 1621, + 1617, 1620, 1620, 1622, 1621, 1621, 1619, 1622, 1623, 1624, + 1624, 1625, 1626, 1627, 1628, 1629, 1630, 1631, 1632, 1628, + 1634, 1629, 1627, 1633, 1635, 1637, 1634, 1636, 1623, 1635, + 1625, 1626, 1638, 1636, 1639, 1630, 1631, 1640, 1632, 1641, + + 1642, 1633, 1640, 1637, 1643, 1644, 1642, 1645, 1646, 1639, + 1647, 1644, 1638, 1645, 1648, 1649, 1650, 1651, 1652, 1647, + 1653, 1656, 1654, 1643, 1656, 1641, 1657, 1646, 1655, 1655, + 1658, 1659, 1652, 1648, 1649, 1650, 1651, 1654, 1660, 1660, + 1663, 1653, 1664, 1659, 1663, 1657, 1661, 1661, 1662, 1658, + 1665, 1666, 1673, 1662, 1667, 1664, 1670, 1673, 1670, 1674, + 1666, 1676, 1670, 1672, 1672, 1665, 1675, 1667, 1677, 1675, + 1676, 1678, 1679, 1677, 1680, 1670, 1682, 1674, 1681, 1681, + 1684, 1682, 1683, 1685, 1687, 1686, 1678, 1690, 1683, 1687, + 1680, 1686, 1679, 1688, 1689, 1684, 1685, 1688, 1689, 1691, + + 1692, 1693, 1694, 1695, 1695, 1697, 1699, 1690, 1694, 1692, + 1700, 1701, 1699, 1702, 1702, 1704, 1701, 1691, 1703, 1706, + 1706, 1693, 1708, 1697, 1703, 1708, 1709, 1709, 1710, 1711, + 1712, 1700, 1715, 1714, 1716, 1704, 1714, 1718, 1717, 1719, + 1719, 1720, 1721, 1722, 1710, 1711, 1712, 1717, 1729, 1723, + 1724, 1725, 1726, 1715, 1716, 1724, 1720, 1718, 1726, 1727, + 1727, 1728, 1722, 1721, 1723, 1725, 1729, 1730, 1731, 1732, + 1728, 1733, 1733, 1734, 1735, 1736, 1737, 1738, 1738, 1739, + 1736, 1740, 1730, 1739, 1741, 1741, 1742, 1734, 1743, 1732, + 1744, 1737, 1735, 1731, 1745, 1746, 1747, 1748, 1749, 1746, + + 1761, 1740, 1748, 1751, 1751, 1745, 1742, 1752, 1753, 1744, + 1743, 1753, 1752, 1752, 1754, 1747, 1755, 1756, 1749, 1757, + 1758, 1755, 1759, 1762, 1760, 1761, 1764, 1754, 1763, 1763, + 1765, 1764, 1762, 1756, 1758, 1766, 1767, 1757, 1760, 1769, + 1766, 1759, 1759, 1768, 1770, 1770, 1768, 1772, 1771, 1773, + 1765, 1774, 1772, 1774, 1775, 1776, 1767, 1771, 1769, 1775, + 1777, 1776, 1778, 1781, 1783, 1779, 1782, 1782, 1778, 1773, + 1779, 1784, 1790, 1785, 1788, 1786, 1794, 1781, 1785, 1788, + 1777, 1786, 1789, 1783, 1791, 1791, 1793, 1789, 1792, 1792, + 1784, 1795, 1796, 1798, 1794, 1796, 1790, 1797, 1797, 1800, + + 1793, 1799, 1801, 1802, 1803, 1801, 1795, 1804, 1801, 1807, + 1803, 1798, 1804, 1799, 1805, 1802, 1808, 1805, 1807, 1800, + 1801, 1808, 1809, 1810, 1811, 1811, 1810, 1812, 1813, 1814, + 1820, 1815, 1821, 1805, 1813, 1814, 1815, 1816, 1816, 1817, + 1817, 1819, 1818, 1820, 1822, 1823, 1819, 1809, 1818, 1824, + 1821, 1812, 1824, 1825, 1826, 1827, 1830, 1828, 1829, 1825, + 1826, 1827, 1828, 1822, 1829, 1823, 1831, 1832, 1832, 1833, + 1834, 1831, 1835, 1837, 1833, 1836, 1838, 1839, 1844, 1830, + 1840, 1843, 1841, 1845, 1842, 1847, 1848, 1845, 1834, 1850, + 1836, 1837, 1835, 1848, 1840, 1838, 1841, 1839, 1842, 1843, + + 1846, 1850, 1846, 1844, 1847, 1851, 1852, 1853, 1854, 1855, + 1856, 1858, 1857, 1853, 1858, 1859, 1859, 1851, 1860, 1852, + 1862, 1862, 1863, 1865, 1864, 1855, 1857, 1860, 1854, 1864, + 1856, 1867, 1858, 1866, 1866, 1865, 1868, 1869, 1870, 1871, + 1874, 1872, 1863, 1873, 1872, 1881, 1867, 1874, 1871, 1876, + 1868, 1875, 1878, 1880, 1961, 1872, 1870, 1872, 1873, 1872, + 1875, 1869, 1961, 1875, 1886, 1876, 1882, 1878, 1885, 1882, + 1881, 1880, 1878, 1883, 1883, 1884, 1884, 1887, 1888, 1889, + 1885, 1888, 1886, 1890, 1890, 1891, 1887, 1892, 1893, 1896, + 1894, 1895, 1896, 1893, 1889, 1897, 1895, 1898, 1891, 1899, + + 1900, 1901, 1902, 1903, 1899, 1905, 1892, 1894, 1910, 1904, + 17, 1902, 1908, 1908, 1906, 1898, 1897, 1901, 1904, 1900, + 1907, 1904, 1903, 1906, 1909, 1911, 1907, 1912, 1910, 1905, + 1913, 1909, 1914, 1920, 1915, 1917, 1916, 1921, 1911, 1915, + 1915, 1916, 1922, 1922, 1913, 1912, 1923, 1917, 1914, 1923, + 1924, 1925, 1926, 1926, 0, 1921, 1928, 1926, 1920, 1929, + 1925, 1927, 1927, 1934, 1930, 1928, 1924, 1930, 1928, 1931, + 1932, 1932, 1933, 1929, 1931, 1933, 1927, 1935, 1936, 1937, + 1939, 1934, 1940, 1941, 1937, 1937, 1942, 1943, 1945, 1944, + 1953, 1942, 1946, 1946, 1939, 1944, 1936, 1940, 1935, 1948, + + 1949, 1943, 1947, 1950, 1948, 1941, 1945, 1951, 1947, 1950, + 1953, 1954, 1955, 1951, 1949, 1956, 1957, 1959, 1963, 1958, + 1964, 1956, 1958, 1959, 1965, 1966, 1955, 1967, 1958, 1957, + 1975, 1954, 1967, 1966, 1969, 1968, 1970, 1963, 1971, 1964, + 1972, 1973, 1975, 1965, 1968, 1970, 1976, 1969, 1974, 1974, + 1977, 1971, 1976, 1979, 1972, 1973, 1977, 1978, 1980, 1980, + 1978, 1981, 1982, 1983, 1984, 1984, 1979, 1986, 1987, 1988, + 1974, 1985, 0, 1986, 1989, 1991, 1991, 1992, 1994, 1993, + 1982, 1981, 1983, 1993, 1985, 1988, 1995, 1996, 1997, 1998, + 1987, 1995, 1989, 1997, 1998, 1999, 2000, 1992, 1994, 2001, + + 2003, 2005, 2006, 2003, 1999, 2008, 2007, 1996, 2001, 2007, + 2009, 2006, 2005, 2011, 2003, 2010, 2010, 2008, 2012, 2000, + 2013, 2014, 2014, 2015, 2016, 2009, 2017, 2019, 2015, 2018, + 2012, 2020, 2011, 2017, 2019, 2021, 2022, 2025, 2016, 2013, + 2024, 2018, 2026, 2020, 2028, 2029, 2021, 2031, 2026, 2027, + 2031, 2029, 2030, 2030, 2032, 2035, 2022, 2025, 2037, 2024, + 2035, 2027, 2028, 2033, 2033, 2036, 2038, 2039, 2041, 2041, + 2040, 2036, 2042, 2037, 2032, 2038, 2040, 2043, 2044, 2043, + 2045, 2044, 2046, 2039, 2042, 2047, 2049, 2048, 2050, 2051, + 2052, 2049, 2053, 2050, 2054, 2057, 2055, 2056, 2051, 2054, + + 2045, 2055, 2052, 2047, 2046, 2048, 2056, 2053, 2058, 2059, + 2060, 2061, 2061, 2058, 2059, 2057, 2062, 2063, 2065, 2056, + 2058, 2066, 2062, 2067, 2069, 2060, 2070, 2068, 2070, 2072, + 2072, 2071, 2073, 2073, 2065, 2074, 2074, 2075, 2063, 2078, + 2066, 2079, 2067, 2068, 2069, 2071, 2080, 2071, 2076, 2076, + 2077, 2077, 2081, 2081, 2082, 2083, 2084, 2075, 2082, 2084, + 2078, 2083, 2079, 2086, 2087, 2088, 2089, 2080, 2090, 2086, + 2091, 2088, 2092, 2093, 2095, 2091, 2093, 2090, 2094, 2094, + 2096, 2098, 2087, 2097, 2097, 2096, 2099, 2100, 2101, 2089, + 2102, 2102, 2100, 2101, 2095, 2103, 2098, 2092, 2104, 2105, + + 2103, 2106, 2107, 2108, 2104, 2110, 2111, 2099, 2109, 2112, + 2113, 2105, 2105, 2105, 2109, 2113, 2112, 2116, 2105, 2117, + 2107, 2106, 2115, 2108, 2119, 2110, 2111, 2115, 2115, 2120, + 2118, 2116, 2118, 2121, 2117, 2119, 2122, 2123, 2124, 2121, + 2125, 2128, 2126, 2127, 2120, 2122, 2129, 2129, 2130, 2131, + 2131, 2132, 2124, 2133, 2134, 2134, 2137, 2123, 2141, 2125, + 2126, 2127, 2128, 2135, 2135, 2136, 2136, 2140, 2140, 2142, + 2143, 2132, 2146, 2142, 2130, 2133, 2137, 2144, 2144, 2143, + 2147, 2146, 2148, 2141, 2149, 2150, 2151, 2153, 2148, 2152, + 2154, 2154, 2155, 2153, 2156, 2159, 2160, 2160, 2158, 2157, + + 2162, 2147, 2151, 2152, 2150, 2149, 2157, 2158, 2163, 2156, + 2161, 2161, 2165, 2155, 2166, 2168, 2167, 2170, 2165, 2166, + 2169, 2159, 2167, 2170, 2163, 2173, 2162, 2169, 2171, 2176, + 2171, 2174, 2175, 2175, 2176, 2168, 2177, 2174, 2178, 2179, + 2181, 2180, 2182, 2181, 2173, 2177, 2183, 2184, 2185, 2183, + 2186, 2186, 2187, 2178, 2182, 2188, 2187, 2189, 2190, 2179, + 2180, 2191, 2191, 2189, 2193, 2184, 2192, 2194, 2197, 2195, + 2190, 2198, 2192, 2195, 2185, 2188, 2199, 2200, 2200, 2201, + 2202, 2199, 2194, 2203, 2193, 2205, 2206, 2209, 2197, 2195, + 2206, 2207, 2207, 2198, 2208, 2215, 2209, 2211, 2203, 2202, + + 2208, 2210, 2210, 2201, 2205, 2212, 2211, 2213, 2216, 2212, + 2214, 2214, 2217, 2219, 2218, 2220, 2215, 2221, 2213, 2218, + 2222, 2223, 2216, 2213, 2225, 2224, 2222, 2231, 2226, 2225, + 2229, 2217, 2232, 2219, 2229, 2220, 2231, 2221, 2233, 2223, + 2224, 2226, 2227, 2227, 2228, 2228, 2234, 2235, 2243, 2233, + 2271, 2232, 2235, 2271, 2233, 2236, 2236, 2238, 2238, 2239, + 2245, 2240, 2242, 2246, 2239, 2239, 2234, 2240, 2242, 2246, + 2244, 2248, 2245, 2249, 2243, 2244, 2250, 2249, 2251, 2252, + 2252, 2250, 2253, 2248, 2255, 2254, 2256, 2257, 2258, 2259, + 2251, 2254, 2256, 2261, 2259, 2260, 2260, 2262, 2264, 2263, + + 2267, 2266, 2257, 2258, 2263, 2276, 2255, 2253, 2278, 2268, + 2264, 2276, 2261, 2266, 2268, 2270, 2270, 2262, 2277, 2267, + 2272, 2272, 2273, 2273, 2274, 2274, 2275, 2275, 2278, 2279, + 2280, 2290, 2281, 2277, 2282, 2279, 2280, 2281, 2283, 2285, + 2282, 2291, 2288, 2286, 2285, 2288, 2289, 2283, 2286, 2286, + 2289, 2292, 2290, 2291, 2293, 2293, 2295, 2296, 2297, 2298, + 2298, 2299, 2300, 2297, 2303, 2303, 2292, 2300, 2295, 2296, + 2299, 2301, 2302, 2304, 2305, 2302, 2301, 2306, 2307, 2308, + 2309, 2310, 2311, 2305, 2309, 2308, 2310, 2312, 2311, 2313, + 2314, 2318, 2315, 2304, 2319, 2306, 2321, 2307, 2313, 2317, + + 2317, 2320, 2333, 2319, 2325, 2312, 2315, 2324, 2314, 2318, + 2320, 2317, 2322, 2322, 2323, 2326, 2321, 2327, 2333, 2324, + 2326, 2330, 2330, 2323, 2332, 2325, 2334, 2332, 2335, 2338, + 2327, 2337, 2339, 2340, 2341, 2341, 0, 2342, 2339, 2342, + 2343, 2344, 2334, 2338, 2335, 2345, 2337, 2344, 2346, 2346, + 2340, 2347, 2349, 2349, 2343, 2350, 2350, 2352, 2353, 2347, + 2354, 2355, 2356, 2345, 2353, 2357, 2354, 2362, 2358, 2356, + 2359, 2359, 2360, 2360, 2361, 2355, 2364, 2363, 2365, 2362, + 2352, 2360, 2366, 2367, 2368, 2373, 2370, 2357, 2358, 2363, + 2365, 2364, 2367, 2374, 2378, 2361, 2369, 2376, 2376, 2368, + + 2375, 2369, 2369, 2377, 2371, 2373, 2371, 2371, 2366, 2370, + 2371, 2383, 2375, 2384, 2378, 2379, 2374, 2380, 2379, 2381, + 2381, 2377, 2380, 2371, 2382, 2382, 2383, 2385, 2387, 2388, + 2389, 2388, 2384, 2387, 2390, 2391, 2394, 2396, 2400, 2390, + 2397, 2397, 2391, 2398, 2401, 2394, 2401, 2385, 2389, 2402, + 2400, 2403, 2398, 2404, 2405, 2396, 2406, 2409, 2407, 2409, + 2405, 2410, 2411, 2411, 2412, 2413, 2403, 2414, 2402, 2414, + 2413, 2418, 2420, 2404, 2416, 2410, 2406, 2407, 2407, 2416, + 2417, 2419, 2421, 2423, 2428, 2417, 2422, 0, 2421, 2418, + 2412, 2422, 2420, 2424, 2426, 2425, 2423, 2429, 2430, 2419, + + 2425, 2425, 2426, 2428, 2433, 2424, 2431, 2431, 2432, 2432, + 2430, 2429, 2434, 2435, 2436, 2433, 2437, 2438, 2439, 2438, + 2436, 2437, 2440, 2441, 2439, 2442, 2443, 2434, 2440, 2444, + 2446, 2442, 2443, 2435, 2445, 2445, 2451, 2444, 2447, 2447, + 2449, 2441, 2446, 2448, 2448, 2444, 2450, 2454, 2453, 2449, + 2456, 2450, 2453, 2455, 2451, 2455, 2454, 2457, 2458, 2454, + 2459, 2460, 2457, 2457, 2462, 2475, 2463, 2464, 2467, 2459, + 2458, 2456, 2464, 2460, 2465, 2468, 2469, 2462, 2463, 2465, + 2471, 2467, 2472, 2468, 2473, 2469, 2470, 2470, 2474, 2476, + 2475, 2477, 2478, 2480, 2482, 2468, 2481, 2478, 2471, 2487, + + 2472, 2496, 2473, 2476, 2474, 2480, 2477, 2484, 2481, 2483, + 2483, 2485, 2484, 2486, 2482, 2490, 2485, 2487, 2492, 2493, + 2494, 2490, 2486, 2495, 2492, 2500, 2496, 2497, 2498, 2498, + 2499, 2501, 2501, 2502, 2490, 2494, 2497, 2503, 2500, 2499, + 2504, 2495, 2493, 2505, 2504, 2506, 2507, 2508, 2505, 2509, + 2513, 2502, 2511, 2512, 2520, 2522, 2503, 2515, 2506, 2512, + 2507, 2514, 2508, 2515, 2516, 2517, 2514, 2514, 2517, 2509, + 2516, 2511, 2513, 2519, 2520, 2522, 2524, 2525, 2526, 2526, + 2528, 2519, 2527, 2527, 2529, 2529, 2530, 2530, 2531, 2528, + 2533, 2532, 2535, 2537, 2539, 2525, 2533, 2527, 2535, 2524, + + 2531, 2536, 2538, 2540, 2540, 2541, 2541, 2538, 2527, 2532, + 2542, 2543, 2539, 2537, 2545, 2542, 2536, 2543, 2545, 2546, + 2547, 2548, 2550, 2551, 2547, 2552, 2554, 2553, 2551, 2555, + 2557, 2556, 2558, 2559, 2555, 2560, 2561, 2561, 2559, 2546, + 2563, 2548, 2553, 2565, 2554, 2566, 2557, 2550, 2552, 2556, + 2562, 2564, 2558, 2568, 2562, 2563, 2564, 2560, 2567, 2569, + 2571, 2565, 2570, 2572, 2575, 2568, 2576, 2570, 2573, 2573, + 2577, 2566, 2575, 2571, 2578, 2579, 2567, 2580, 2569, 2582, + 2581, 2572, 2583, 2584, 2585, 2576, 2586, 2589, 0, 2577, + 2585, 2587, 2591, 2578, 2583, 2586, 2592, 2587, 2579, 2581, + + 2582, 2580, 2589, 2593, 2584, 2591, 2594, 2595, 2594, 2593, + 2592, 2596, 2596, 2597, 2598, 2599, 2600, 2598, 2597, 2601, + 2624, 2602, 2603, 2603, 2604, 2604, 2607, 2595, 2599, 2605, + 2608, 2605, 2624, 2601, 2602, 2606, 2606, 2609, 2610, 2610, + 2600, 2607, 2610, 2612, 2612, 2608, 2613, 2613, 2614, 2616, + 2609, 2615, 2615, 2617, 2617, 2618, 2618, 2619, 2616, 2621, + 2622, 2616, 2619, 2614, 2621, 2623, 2625, 2628, 2627, 2629, + 2629, 2630, 2630, 2631, 2632, 2632, 2628, 2633, 2635, 2625, + 2622, 2627, 2634, 2634, 2636, 2623, 2638, 2638, 2640, 2636, + 2639, 2639, 2631, 2635, 2641, 2633, 2642, 2643, 2643, 2646, + + 2644, 2647, 2640, 2641, 2645, 2645, 2648, 2649, 2646, 2651, + 2647, 2652, 2652, 2653, 2651, 2655, 2642, 2644, 2654, 2654, + 2648, 2658, 2656, 2657, 2658, 2661, 2649, 2656, 2662, 2657, + 2659, 2659, 2653, 2655, 2660, 2660, 2663, 2665, 2663, 2666, + 2667, 2667, 2668, 2662, 2661, 2670, 2659, 2671, 2668, 2672, + 2674, 2673, 2665, 2677, 2674, 2675, 2675, 2676, 2666, 2678, + 2680, 2686, 2671, 2679, 2680, 2670, 2673, 2682, 2679, 2683, + 2683, 2681, 2672, 2677, 2681, 2688, 2676, 2685, 2685, 2678, + 2687, 2686, 2682, 2681, 2683, 2689, 2690, 2687, 2692, 2688, + 2681, 2681, 2691, 2693, 2693, 2695, 2694, 2695, 2696, 2699, + + 2698, 2696, 2703, 2689, 2690, 2694, 2698, 2691, 2700, 2704, + 2701, 2699, 2702, 2700, 2692, 2701, 2696, 2702, 2696, 2705, + 2706, 2707, 2704, 2708, 2713, 2710, 2707, 2703, 2711, 2706, + 2710, 2712, 2714, 2711, 2716, 2715, 2712, 2717, 2714, 2713, + 2705, 2715, 2718, 2722, 2723, 2719, 2720, 2725, 2718, 2708, + 2719, 2720, 2717, 2724, 2726, 2716, 2724, 2723, 2730, 2731, + 2727, 2728, 2729, 2726, 2735, 2731, 2736, 2725, 2722, 2727, + 2728, 2729, 2730, 2732, 2733, 2738, 2739, 2741, 2733, 2732, + 2740, 2740, 2736, 2741, 2735, 2739, 2743, 2742, 2742, 2744, + 2746, 2745, 2743, 2745, 2749, 2738, 2742, 2747, 2747, 2746, + + 2744, 2748, 2751, 2752, 2753, 2753, 2748, 2754, 2755, 2761, + 2758, 2756, 2760, 2757, 2749, 2758, 2749, 2755, 2751, 2752, + 2756, 2757, 2754, 2762, 2760, 2761, 2765, 2763, 2766, 2765, + 2767, 2768, 2769, 2766, 2770, 2770, 2771, 2771, 2762, 2763, + 2768, 2772, 2772, 2773, 2769, 2774, 2774, 2776, 2776, 2777, + 2767, 2778, 2777, 2779, 2780, 2781, 2778, 2782, 2782, 2779, + 2780, 2783, 2785, 2773, 2781, 2784, 2784, 2786, 2786, 2787, + 2788, 2789, 2789, 2790, 2785, 2783, 2791, 2792, 2795, 2790, + 2794, 2795, 2792, 2787, 2794, 2796, 2796, 2797, 2798, 2788, + 2791, 2799, 2797, 2798, 2800, 2801, 2804, 2802, 2803, 2803, + + 2799, 2802, 2806, 2800, 2807, 2808, 2809, 2806, 2810, 2804, + 2811, 2812, 2813, 2814, 2811, 2801, 2819, 2813, 2817, 2814, + 2820, 2815, 2810, 2817, 2807, 2808, 2809, 2815, 2816, 2816, + 2821, 2812, 2818, 2818, 2819, 2822, 2823, 2824, 2824, 2820, + 2822, 2826, 2827, 2828, 2829, 2830, 2831, 2834, 2828, 2821, + 2829, 2830, 2836, 2826, 2831, 2837, 2834, 2823, 2827, 2832, + 2843, 2832, 2838, 2838, 2839, 2842, 2836, 2839, 2842, 2837, + 2840, 2840, 2845, 2844, 2850, 2843, 2844, 2846, 2846, 2849, + 2850, 2851, 2853, 2849, 2852, 2852, 2855, 2854, 2861, 2856, + 2863, 2853, 2854, 2851, 2864, 2855, 2856, 2867, 2845, 2859, + + 2859, 2868, 2867, 2870, 2863, 2871, 2861, 2869, 2869, 2873, + 2864, 2874, 2875, 2876, 2877, 2877, 2881, 2875, 2876, 2879, + 2879, 2870, 2881, 2882, 2874, 2884, 2871, 2868, 2883, 2883, + 2885, 2886, 2888, 2890, 2889, 2873, 2886, 2889, 2891, 2892, + 2892, 2884, 2894, 2882, 2895, 2890, 2898, 2899, 2896, 2897, + 2891, 2888, 2885, 2895, 2896, 2897, 2901, 2901, 2894, 2902, + 2903, 2906, 2899, 2904, 2898, 2905, 2904, 2905, 2902, 2903, + 2907, 2909, 2908, 2910, 2911, 2919, 2906, 2908, 2912, 2917, + 2909, 2914, 2914, 2915, 2915, 2907, 2916, 2926, 2919, 2918, + 2920, 2916, 2910, 2911, 2911, 2920, 2912, 2917, 2918, 2921, + + 2922, 2921, 2923, 2924, 2925, 2927, 2928, 2926, 2930, 2925, + 0, 2928, 2929, 2929, 2922, 2924, 2923, 2931, 2931, 2932, + 2932, 2933, 2933, 2930, 2934, 2927, 2935, 2936, 2935, 2937, + 2938, 2938, 2939, 2939, 2937, 2941, 2934, 2940, 2940, 2942, + 2943, 2944, 2945, 2948, 2946, 2936, 2951, 2941, 2947, 2947, + 2949, 2949, 2943, 2950, 2950, 2952, 2952, 2951, 2953, 2942, + 2946, 2944, 2948, 2945, 2954, 2955, 2956, 2957, 2958, 2959, + 2953, 2954, 2957, 2960, 2960, 2961, 2962, 2955, 2963, 2963, + 2964, 2965, 2966, 2967, 2961, 2968, 2956, 2972, 2958, 2959, + 2969, 2969, 2971, 2970, 2981, 2966, 2962, 2977, 2973, 2968, + + 2973, 2965, 2970, 2974, 2971, 2976, 2964, 2967, 2978, 2972, + 2975, 2975, 2977, 2980, 2976, 2974, 2981, 2982, 2985, 2983, + 2984, 2984, 2986, 2978, 2983, 2986, 2987, 2988, 2989, 2990, + 2990, 2980, 2988, 2989, 2991, 2991, 2992, 2993, 2993, 2982, + 2987, 2985, 2997, 2998, 2998, 3000, 3000, 3001, 2992, 3002, + 3003, 2997, 3004, 3006, 3007, 3008, 3009, 3011, 3010, 3012, + 3002, 3013, 3014, 3013, 0, 3001, 3011, 3004, 3015, 3003, + 3016, 3021, 3007, 3006, 3017, 3017, 3009, 3008, 3010, 3012, + 3019, 3022, 3014, 3023, 3019, 3021, 3015, 3026, 3016, 3020, + 3020, 3028, 3023, 3024, 3024, 3029, 3026, 3027, 3027, 3030, + + 3031, 3032, 3033, 3022, 3034, 3035, 3036, 3031, 3037, 3028, + 3038, 3039, 3037, 3029, 3038, 3042, 3032, 3030, 3039, 3043, + 3033, 3035, 3034, 3040, 3040, 3036, 3041, 3041, 3044, 3046, + 3046, 3047, 3047, 3048, 3044, 3042, 3049, 3043, 3050, 3048, + 3051, 3052, 3054, 3053, 3055, 3055, 3056, 3054, 3057, 3058, + 3059, 3060, 3061, 3062, 3049, 3051, 3050, 3053, 3062, 3068, + 3052, 3059, 3060, 3063, 3070, 3063, 3056, 3074, 3057, 3058, + 3064, 3064, 3061, 3065, 3076, 3065, 3066, 3066, 3068, 3069, + 3069, 3071, 3071, 3070, 3073, 3075, 3074, 3077, 3078, 3078, + 3079, 3080, 3077, 3073, 3076, 3081, 3080, 3075, 3082, 3083, + + 3081, 3084, 3087, 3082, 3089, 3088, 3091, 3089, 3090, 3090, + 3079, 3092, 3093, 3093, 3094, 3095, 3098, 3099, 0, 3083, + 3084, 3091, 3087, 3088, 3096, 3094, 3103, 3100, 3096, 3092, + 3095, 3098, 3099, 3100, 3101, 3102, 3102, 3105, 3101, 3103, + 3106, 3107, 3108, 3108, 3109, 3110, 3111, 3112, 3113, 3116, + 3105, 3114, 3110, 3106, 3115, 3119, 3107, 3109, 3109, 3124, + 3112, 0, 3115, 3120, 3111, 3117, 3117, 3119, 3113, 3116, + 3114, 3121, 3120, 3122, 3122, 3121, 3123, 3123, 3124, 3125, + 3125, 3126, 3127, 3128, 3129, 3130, 3126, 3131, 3131, 3133, + 3139, 3127, 3137, 3137, 3138, 3141, 3129, 3140, 3140, 3128, + + 3142, 3143, 3144, 3138, 3148, 3130, 3145, 3146, 3141, 0, + 3133, 3144, 3139, 3142, 3143, 3145, 3146, 3147, 3147, 3149, + 3151, 3151, 3154, 3156, 3148, 3157, 3158, 3154, 3156, 3159, + 3160, 3158, 3161, 3164, 3149, 3162, 3165, 3159, 3169, 3157, + 3167, 3161, 3168, 3162, 3172, 3167, 3174, 3168, 3164, 3160, + 3170, 3170, 3176, 3169, 3173, 3165, 3171, 3171, 3175, 3173, + 3178, 3174, 3180, 3175, 3172, 3177, 3177, 3178, 3179, 3181, + 3182, 3176, 3183, 3179, 3184, 3185, 3182, 3183, 3188, 3184, + 3180, 3187, 3187, 3189, 3190, 3190, 3195, 3181, 3189, 3185, + 3191, 3191, 3194, 3188, 3196, 3197, 3197, 3194, 3198, 3195, + + 3199, 3198, 3200, 3202, 3201, 3199, 3199, 3200, 3196, 3201, + 3203, 3204, 3207, 3205, 3206, 3204, 3203, 3202, 3205, 3206, + 3208, 3207, 3209, 3210, 3213, 3211, 3212, 3214, 3221, 3213, + 3209, 3211, 3212, 3215, 3215, 3208, 3217, 3218, 3219, 3214, + 3221, 3219, 3218, 3217, 3210, 3223, 3224, 3225, 3226, 3227, + 3223, 3224, 3225, 3233, 3228, 3229, 3230, 3230, 3231, 3233, + 3237, 3232, 3227, 3228, 3229, 3232, 3226, 3231, 3234, 3238, + 3239, 3242, 3243, 3234, 3244, 3238, 3239, 3245, 3237, 3246, + 3246, 3247, 3248, 0, 3250, 3253, 3251, 3255, 3247, 3261, + 3242, 3257, 3243, 3250, 3244, 3251, 3245, 3252, 3252, 3254, + + 3253, 3248, 3255, 3256, 3256, 3259, 3266, 3266, 3254, 3261, + 3257, 3263, 3265, 3267, 3263, 3268, 3265, 3269, 3271, 3278, + 3259, 3268, 3272, 3269, 3273, 3273, 3274, 3274, 3275, 3276, + 3276, 3277, 3282, 3281, 3275, 3287, 3279, 3271, 3267, 3277, + 3272, 3279, 3281, 3284, 3278, 3282, 3288, 3285, 3286, 3284, + 3285, 3290, 3286, 3287, 3289, 3289, 3292, 3292, 3293, 3294, + 3288, 3295, 3297, 3293, 3294, 3299, 3290, 3298, 3300, 3302, + 3302, 3301, 3303, 0, 3299, 3297, 3301, 3304, 3304, 3295, + 3310, 3298, 3305, 3305, 3307, 3307, 3314, 3308, 3309, 3310, + 3300, 3308, 3316, 3309, 3315, 3303, 3312, 3312, 3318, 3315, + + 3320, 3321, 3317, 3322, 3316, 0, 3314, 3317, 3317, 3335, + 3318, 3323, 3323, 3325, 3325, 3326, 3326, 3327, 3327, 3328, + 3320, 3321, 3328, 3322, 3329, 3330, 3332, 3332, 3333, 3335, + 3336, 3336, 3337, 3337, 3338, 3338, 3339, 3329, 3330, 3340, + 3340, 3341, 3342, 3343, 3344, 3344, 3333, 3345, 3346, 3346, + 3350, 3339, 3347, 3345, 3341, 3353, 3347, 3343, 3351, 3352, + 3342, 3353, 3352, 3351, 3351, 3357, 3354, 3356, 3364, 3358, + 3350, 3354, 3356, 3356, 3359, 3360, 3361, 3362, 3363, 3366, + 3366, 3360, 3361, 3362, 3363, 3376, 3365, 0, 3357, 3358, + 3365, 3369, 3369, 3364, 3359, 3370, 3371, 3373, 3374, 3377, + + 3370, 3374, 3377, 3371, 3379, 3373, 3378, 3378, 3380, 3381, + 3376, 3382, 3382, 3380, 3383, 3384, 3385, 3385, 3386, 3388, + 3387, 3379, 3379, 3387, 3389, 3395, 3395, 3381, 3390, 3384, + 3394, 3387, 3386, 3388, 3383, 3392, 3390, 3396, 3396, 3393, + 3392, 3392, 3401, 3389, 3393, 3393, 3397, 3397, 3403, 3394, + 3398, 3398, 3399, 3399, 3400, 3400, 3402, 3404, 3401, 3406, + 3405, 3402, 3407, 3409, 3411, 3408, 3406, 3410, 3403, 3405, + 3408, 3412, 3410, 3411, 3413, 3414, 3407, 3416, 3416, 3417, + 3417, 3418, 3409, 3404, 3418, 3419, 3420, 3420, 3422, 3423, + 3421, 3412, 3426, 3422, 3413, 3414, 3421, 3425, 3425, 3426, + + 3419, 3427, 3427, 3428, 3429, 3431, 3431, 3423, 3432, 3429, + 3433, 3434, 3434, 3435, 3438, 3440, 3445, 3432, 3446, 3433, + 3441, 3441, 3435, 3438, 3428, 3442, 3442, 3443, 3444, 3446, + 3447, 3443, 3448, 3440, 3449, 3445, 3451, 3444, 3452, 3449, + 3449, 3453, 3454, 3458, 3455, 3447, 3458, 3452, 3455, 3451, + 3456, 3456, 3448, 3457, 3459, 3460, 3453, 3454, 3457, 3459, + 3462, 3466, 3467, 3467, 3468, 3471, 3466, 3470, 3470, 3472, + 3460, 3473, 3475, 3475, 3477, 3462, 3476, 3476, 3468, 3471, + 3478, 3479, 3483, 3477, 3487, 3484, 3478, 3485, 3490, 3473, + 3484, 3488, 3492, 3479, 3472, 3535, 3485, 3488, 3494, 3535, + + 3490, 3495, 3498, 3494, 3487, 3500, 3495, 3483, 3496, 3496, + 3500, 3498, 3501, 3492, 3502, 3504, 3505, 3501, 3506, 3507, + 3507, 3509, 3509, 3507, 3510, 3510, 3504, 3512, 3502, 3505, + 3511, 3511, 3506, 3513, 3514, 3517, 3512, 3515, 3516, 3520, + 3517, 3521, 3521, 3522, 3523, 3520, 3524, 3524, 3522, 3523, + 3525, 3526, 3527, 3513, 3514, 3528, 3515, 3516, 3529, 3530, + 3528, 3532, 3539, 3526, 3536, 3530, 3533, 3533, 3525, 3536, + 3537, 3538, 3538, 3527, 3540, 3537, 3529, 3541, 3543, 3545, + 3545, 3539, 3547, 3548, 3549, 3551, 3532, 3550, 3552, 3540, + 3553, 3550, 3541, 3554, 3551, 3547, 3548, 3549, 3543, 3556, + + 3555, 3554, 3557, 3558, 3552, 3555, 3559, 3559, 3560, 3553, + 3561, 3562, 3563, 3563, 3557, 3564, 3564, 3560, 3569, 3556, + 3565, 3568, 3575, 3558, 3571, 3577, 3568, 3568, 3561, 3580, + 3571, 3581, 3569, 3572, 3572, 3573, 3573, 3562, 3584, 3565, + 3577, 3578, 3578, 3575, 3583, 3580, 3585, 3581, 3589, 3583, + 3590, 3585, 3588, 3588, 3584, 3591, 3592, 3593, 3593, 3590, + 3597, 3591, 3594, 3596, 3596, 3598, 3599, 3604, 3589, 3600, + 3601, 3605, 3602, 3606, 3597, 3602, 3603, 3603, 3611, 3592, + 3616, 3594, 3607, 3607, 3601, 3604, 3598, 3599, 3600, 3609, + 3612, 3606, 3605, 3617, 3613, 3609, 3612, 3620, 3611, 3613, + + 3618, 3618, 3616, 3619, 3619, 3621, 3622, 3622, 3624, 3623, + 3625, 3628, 3620, 3627, 3629, 3626, 3631, 3624, 3634, 3617, + 3623, 3626, 3833, 3628, 3833, 3621, 3622, 3630, 3630, 3631, + 3625, 3632, 3627, 3634, 3629, 3641, 3632, 3633, 3633, 3635, + 3636, 3642, 3635, 3636, 3637, 3637, 3643, 3641, 3644, 3645, + 3646, 3646, 3649, 3644, 3647, 3645, 3650, 3647, 3649, 3652, + 3654, 3642, 3653, 3653, 3652, 3654, 3643, 3655, 3660, 3656, + 3657, 3658, 3658, 3661, 3650, 3656, 3662, 3663, 3664, 3664, + 3660, 3665, 3666, 3667, 3669, 3669, 3655, 3657, 3657, 3673, + 3663, 3661, 3667, 3670, 3670, 3671, 3671, 3672, 3666, 3674, + + 3665, 3662, 3672, 3673, 3674, 3675, 3675, 3676, 3676, 3677, + 3677, 3678, 3679, 3680, 3680, 3681, 3682, 3683, 3688, 3684, + 3678, 3687, 3687, 3683, 3684, 3690, 3690, 3694, 3681, 3691, + 3691, 3695, 3697, 3679, 3688, 3698, 3699, 3700, 3701, 3701, + 3703, 3703, 3682, 3704, 3705, 3708, 3694, 3706, 3711, 3709, + 3710, 3710, 3695, 3712, 3697, 3699, 3714, 3698, 3709, 3700, + 3714, 3706, 3715, 3705, 3716, 3708, 3713, 3713, 3711, 3704, + 3718, 3717, 3723, 3712, 3719, 3721, 3716, 3717, 3719, 3722, + 3724, 3725, 3715, 3726, 3729, 3722, 3725, 3734, 3726, 0, + 3718, 3742, 3723, 3721, 3730, 3730, 3732, 3732, 3733, 3724, + + 3735, 3734, 3736, 3733, 3737, 3729, 3735, 3738, 3738, 3741, + 3739, 3742, 3737, 3744, 3736, 3739, 3745, 3744, 3746, 3747, + 3749, 3745, 3748, 3750, 3751, 3741, 3755, 3748, 3752, 3754, + 3756, 3757, 3749, 3760, 3752, 3750, 3759, 3754, 3746, 3747, + 3761, 3762, 3751, 3763, 3766, 3755, 3770, 3765, 3763, 3760, + 3756, 3757, 3765, 3767, 3759, 3768, 3772, 3761, 3761, 3767, + 3768, 3782, 3762, 3778, 3766, 3771, 3770, 3778, 3771, 3772, + 3776, 3776, 3777, 3777, 3783, 3786, 3782, 3785, 3785, 3783, + 3786, 3787, 3788, 3788, 3790, 3793, 3793, 3794, 3795, 3795, + 3799, 3795, 3796, 3796, 3799, 3796, 3797, 3797, 3801, 3790, + + 3787, 3798, 3798, 3801, 3798, 3802, 3794, 3803, 3803, 3804, + 3805, 3807, 3807, 3810, 3802, 3808, 3808, 3811, 3817, 3810, + 3812, 3813, 3818, 3811, 3805, 3821, 3812, 3804, 3822, 3813, + 3814, 3814, 3815, 3815, 3816, 3816, 3819, 3813, 3817, 3820, + 3820, 3819, 3818, 3821, 3825, 3826, 3827, 3828, 3822, 3829, + 3827, 0, 3826, 3831, 3832, 3834, 3828, 3835, 3835, 3836, + 3834, 3837, 3837, 3841, 3829, 3838, 3838, 3842, 3836, 3825, + 3847, 3831, 3839, 3839, 3832, 3840, 3840, 3844, 3843, 3848, + 3849, 3852, 3842, 3843, 3846, 3841, 3844, 3845, 0, 3844, + 3846, 3850, 3845, 3845, 3848, 3847, 3850, 3851, 3853, 3853, + + 3852, 3849, 3851, 3854, 3855, 3856, 3856, 3857, 3857, 3854, + 3855, 3858, 3859, 3862, 3862, 3863, 3867, 3859, 3864, 3864, + 3866, 3866, 3869, 3871, 3871, 3867, 3858, 3872, 3872, 3863, + 3873, 3873, 3874, 3874, 3875, 3875, 3877, 3877, 3878, 3878, + 3869, 3879, 3879, 3880, 3880, 3881, 3883, 3884, 3884, 3887, + 3888, 3890, 3889, 3891, 3891, 3883, 3889, 3894, 3894, 3897, + 3899, 3896, 3901, 3895, 3900, 3900, 3890, 3903, 3891, 3887, + 3888, 3881, 3895, 3896, 3904, 3899, 3902, 3902, 3905, 3897, + 3907, 3901, 3903, 3906, 3906, 3908, 3911, 3904, 3909, 3909, + 3905, 3912, 3912, 3916, 3917, 3919, 3921, 3908, 3916, 3907, + + 3918, 3911, 3924, 3918, 3920, 3920, 3923, 3927, 3924, 3923, + 3925, 3926, 3917, 3928, 3921, 3936, 3926, 3929, 3932, 3931, + 3941, 3919, 3938, 3938, 3925, 3931, 3927, 3932, 3935, 3942, + 3936, 3928, 3935, 3929, 3952, 3953, 3955, 3958, 3953, 3952, + 3957, 3956, 3957, 3959, 3962, 3955, 3941, 3960, 3969, 3942, + 3956, 3963, 3963, 3964, 3964, 3970, 3958, 3962, 3965, 3965, + 3967, 3967, 3959, 3959, 3970, 3960, 3971, 3972, 3973, 3973, + 3971, 3969, 3976, 3974, 3978, 3979, 3981, 3982, 3980, 3982, + 3978, 3981, 3983, 3984, 3984, 3986, 3976, 3972, 3974, 3980, + 3985, 3987, 3988, 3989, 3992, 3990, 3991, 3983, 3979, 3994, + + 3995, 3999, 3993, 3985, 3986, 3991, 3992, 3993, 3988, 3987, + 3990, 3996, 3995, 3997, 3998, 3998, 3996, 4000, 3989, 4003, + 3994, 3999, 4001, 4002, 4002, 4004, 4005, 4006, 4007, 4012, + 4000, 4013, 3997, 4007, 4005, 4001, 4014, 4014, 4017, 4003, + 4015, 4017, 4023, 4012, 4004, 4018, 4018, 4006, 4019, 4015, + 4024, 4013, 4028, 4019, 4020, 4020, 4021, 4021, 4022, 4022, + 4025, 4023, 4026, 4025, 4027, 4029, 4030, 4026, 4031, 4027, + 4024, 4032, 4030, 4033, 4034, 4034, 4035, 4028, 4033, 4045, + 4029, 0, 4031, 4032, 4036, 4036, 4037, 4037, 4038, 4038, + 4040, 4040, 4041, 4042, 4044, 4044, 4035, 4041, 4042, 4046, + + 4046, 4048, 4045, 4047, 4047, 4049, 4050, 4050, 4052, 4053, + 4055, 4056, 4059, 4059, 4060, 4060, 4048, 4061, 4062, 4065, + 4053, 4063, 4064, 4052, 4049, 4061, 4066, 4063, 4064, 4056, + 4067, 4068, 4076, 4065, 4055, 4077, 4068, 4062, 4079, 4066, + 4069, 4069, 4071, 4071, 4082, 4085, 4083, 4076, 4087, 4067, + 4077, 4086, 4086, 4079, 4088, 4090, 4091, 4092, 4088, 4085, + 4093, 4091, 4095, 4096, 4087, 4082, 4083, 4094, 4096, 4097, + 4098, 4098, 4101, 4093, 4097, 4090, 4092, 4102, 4103, 4104, + 4094, 4095, 4105, 4106, 4110, 4108, 4109, 4109, 4116, 4110, + 4113, 4111, 4119, 4101, 4108, 4113, 4103, 4111, 4102, 4104, + + 4105, 4114, 4106, 4112, 4112, 4115, 4114, 4116, 4117, 4120, + 4115, 4121, 4119, 4123, 4117, 4121, 4122, 4122, 4123, 4124, + 4124, 4125, 4127, 4128, 4129, 4130, 4127, 4131, 4132, 4120, + 4133, 4129, 4134, 0, 4132, 4135, 4135, 4136, 4136, 4125, + 4137, 4137, 4128, 4156, 4130, 4134, 4131, 4139, 4139, 4133, + 4141, 4142, 4142, 4143, 4144, 4141, 4145, 4146, 4147, 4144, + 4148, 4148, 4143, 4149, 4153, 4143, 4154, 4158, 4149, 4156, + 4154, 4147, 4157, 4157, 4163, 4145, 4146, 4153, 4159, 4159, + 4160, 4160, 4161, 4162, 4164, 4164, 4158, 4161, 4165, 4165, + 4162, 4166, 4167, 4163, 4167, 4169, 4166, 4168, 4168, 4170, + + 4171, 4173, 4169, 4172, 4176, 4176, 4170, 4177, 4172, 4179, + 4180, 4181, 4182, 4186, 4179, 4180, 4183, 4183, 4187, 4171, + 4173, 4185, 4185, 4188, 4188, 4200, 4177, 4189, 4189, 4190, + 4181, 4182, 4186, 4192, 4192, 4194, 4190, 4187, 4193, 4193, + 4196, 4199, 4194, 4201, 4200, 4196, 4199, 4202, 4202, 4203, + 4203, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 4201, 4207, 4207, 4207, 4207, 4207, 4207, 4207, + 4208, 4208, 4208, 4208, 4208, 4208, 4208, 4209, 4209, 4209, + 4209, 4209, 4209, 4209, 4210, 4210, 4210, 4210, 4210, 4210, + 4210, 4211, 4211, 4211, 4211, 4211, 4211, 4211, 4212, 4212, + + 4212, 4212, 4212, 4212, 4212, 4213, 4213, 4213, 4213, 4213, + 4213, 4213, 4215, 4215, 0, 4215, 4215, 4215, 4215, 4216, + 4216, 0, 0, 0, 4216, 4216, 4217, 4217, 0, 0, + 4217, 0, 4217, 4218, 0, 0, 0, 0, 0, 4218, + 4219, 4219, 0, 0, 0, 4219, 4219, 4220, 0, 0, + 0, 0, 0, 4220, 4221, 4221, 0, 4221, 4221, 4221, + 4221, 4222, 0, 0, 0, 0, 0, 4222, 4223, 4223, + 0, 0, 0, 4223, 4223, 4224, 4224, 0, 4224, 4224, + 4224, 4224, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, + 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, + + 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, + 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, 4206, + 4206, 4206, 4206 } ; static yy_state_type yy_last_accepting_state; @@ -3606,7 +3672,6 @@ char *yytext; #pragma GCC diagnostic ignored "-Wsign-compare" #endif -#include #include #ifdef HAVE_GLOB_H # include @@ -3778,7 +3843,7 @@ static void config_end_include(void) #endif #define YY_NO_INPUT 1 -#line 191 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 190 "/usr/src/usr.sbin/unbound/util/configlexer.lex" #ifndef YY_NO_UNPUT #define YY_NO_UNPUT 1 #endif @@ -3786,7 +3851,7 @@ static void config_end_include(void) #define YY_NO_INPUT 1 #endif -#line 3788 "" +#line 3853 "" #define INITIAL 0 #define quotedstring 1 @@ -4002,9 +4067,9 @@ YY_DECL } { -#line 211 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 210 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -#line 4006 "" +#line 4071 "" while ( 1 ) /* loops until end-of-file is reached */ { @@ -4037,13 +4102,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 >= 4118 ) + if ( yy_current_state >= 4207 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; ++yy_cp; } - while ( yy_base[yy_current_state] != 8023 ); + while ( yy_base[yy_current_state] != 8183 ); yy_find_action: yy_act = yy_accept[yy_current_state]; @@ -4069,1968 +4134,2008 @@ do_action: /* This label is used only to case 1: YY_RULE_SETUP -#line 212 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 211 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("SP ")); /* ignore */ } YY_BREAK case 2: YY_RULE_SETUP -#line 214 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 213 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { /* note that flex makes the longest match and '.' is any but not nl */ LEXOUT(("comment(%s) ", yytext)); /* ignore */ } YY_BREAK case 3: YY_RULE_SETUP -#line 217 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 216 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(0, VAR_SERVER) } YY_BREAK case 4: YY_RULE_SETUP -#line 218 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 217 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_QNAME_MINIMISATION) } YY_BREAK case 5: YY_RULE_SETUP -#line 219 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 218 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_QNAME_MINIMISATION_STRICT) } YY_BREAK case 6: YY_RULE_SETUP -#line 220 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 219 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_NUM_THREADS) } YY_BREAK case 7: YY_RULE_SETUP -#line 221 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 220 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_VERBOSITY) } YY_BREAK case 8: YY_RULE_SETUP -#line 222 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 221 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_PORT) } YY_BREAK case 9: YY_RULE_SETUP -#line 223 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 222 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_OUTGOING_RANGE) } YY_BREAK case 10: YY_RULE_SETUP -#line 224 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 223 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_OUTGOING_PORT_PERMIT) } YY_BREAK case 11: YY_RULE_SETUP -#line 225 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 224 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_OUTGOING_PORT_AVOID) } YY_BREAK case 12: YY_RULE_SETUP -#line 226 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 225 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_OUTGOING_NUM_TCP) } YY_BREAK case 13: YY_RULE_SETUP -#line 227 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 226 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_INCOMING_NUM_TCP) } YY_BREAK case 14: YY_RULE_SETUP -#line 228 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 227 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DO_IP4) } YY_BREAK case 15: YY_RULE_SETUP -#line 229 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 228 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DO_IP6) } YY_BREAK case 16: YY_RULE_SETUP -#line 230 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 229 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DO_NAT64) } YY_BREAK case 17: YY_RULE_SETUP -#line 231 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 230 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_PREFER_IP4) } YY_BREAK case 18: YY_RULE_SETUP -#line 232 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 231 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_PREFER_IP6) } YY_BREAK case 19: YY_RULE_SETUP -#line 233 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 232 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DO_UDP) } YY_BREAK case 20: YY_RULE_SETUP -#line 234 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 233 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DO_TCP) } YY_BREAK case 21: YY_RULE_SETUP -#line 235 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 234 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TCP_UPSTREAM) } YY_BREAK case 22: YY_RULE_SETUP -#line 236 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 235 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TCP_MSS) } YY_BREAK case 23: YY_RULE_SETUP -#line 237 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 236 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_OUTGOING_TCP_MSS) } YY_BREAK case 24: YY_RULE_SETUP -#line 238 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 237 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TCP_IDLE_TIMEOUT) } YY_BREAK case 25: YY_RULE_SETUP -#line 239 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 238 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_MAX_REUSE_TCP_QUERIES) } YY_BREAK case 26: YY_RULE_SETUP -#line 240 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 239 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TCP_REUSE_TIMEOUT) } YY_BREAK case 27: YY_RULE_SETUP -#line 241 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 240 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TCP_AUTH_QUERY_TIMEOUT) } YY_BREAK case 28: YY_RULE_SETUP -#line 242 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 241 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_EDNS_TCP_KEEPALIVE) } YY_BREAK case 29: YY_RULE_SETUP -#line 243 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 242 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_EDNS_TCP_KEEPALIVE_TIMEOUT) } YY_BREAK case 30: YY_RULE_SETUP -#line 244 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 243 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_SOCK_QUEUE_TIMEOUT) } YY_BREAK case 31: YY_RULE_SETUP -#line 245 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 244 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_SSL_UPSTREAM) } YY_BREAK case 32: YY_RULE_SETUP -#line 246 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 245 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_SSL_UPSTREAM) } YY_BREAK case 33: YY_RULE_SETUP -#line 247 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 246 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_SSL_SERVICE_KEY) } YY_BREAK case 34: YY_RULE_SETUP -#line 248 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 247 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_SSL_SERVICE_KEY) } YY_BREAK case 35: YY_RULE_SETUP -#line 249 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 248 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_SSL_SERVICE_PEM) } YY_BREAK case 36: YY_RULE_SETUP -#line 250 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 249 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_SSL_SERVICE_PEM) } YY_BREAK case 37: YY_RULE_SETUP -#line 251 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 250 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_SSL_PORT) } YY_BREAK case 38: YY_RULE_SETUP -#line 252 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 251 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_SSL_PORT) } YY_BREAK case 39: YY_RULE_SETUP -#line 253 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 252 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TLS_CERT_BUNDLE) } YY_BREAK case 40: YY_RULE_SETUP -#line 254 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 253 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TLS_CERT_BUNDLE) } YY_BREAK case 41: YY_RULE_SETUP -#line 255 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 254 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TLS_WIN_CERT) } YY_BREAK case 42: YY_RULE_SETUP -#line 256 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 255 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TLS_WIN_CERT) } YY_BREAK case 43: YY_RULE_SETUP -#line 257 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 256 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) } YY_BREAK case 44: YY_RULE_SETUP -#line 258 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 257 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) } YY_BREAK case 45: YY_RULE_SETUP -#line 259 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 258 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) } YY_BREAK case 46: YY_RULE_SETUP -#line 260 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 259 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TLS_ADDITIONAL_PORT) } YY_BREAK case 47: YY_RULE_SETUP -#line 261 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 260 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TLS_SESSION_TICKET_KEYS) } YY_BREAK case 48: YY_RULE_SETUP -#line 262 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 261 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TLS_CIPHERS) } YY_BREAK case 49: YY_RULE_SETUP -#line 263 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 262 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TLS_CIPHERSUITES) } YY_BREAK case 50: YY_RULE_SETUP -#line 264 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 263 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TLS_USE_SNI) } YY_BREAK case 51: YY_RULE_SETUP +#line 264 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +{ YDVAR(1, VAR_TLS_PROTOCOLS) } + YY_BREAK +case 52: +YY_RULE_SETUP #line 265 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HTTPS_PORT) } YY_BREAK -case 52: +case 53: YY_RULE_SETUP #line 266 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HTTP_ENDPOINT) } YY_BREAK -case 53: +case 54: YY_RULE_SETUP #line 267 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HTTP_MAX_STREAMS) } YY_BREAK -case 54: +case 55: YY_RULE_SETUP #line 268 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HTTP_QUERY_BUFFER_SIZE) } YY_BREAK -case 55: +case 56: YY_RULE_SETUP #line 269 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HTTP_RESPONSE_BUFFER_SIZE) } YY_BREAK -case 56: +case 57: YY_RULE_SETUP #line 270 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HTTP_NODELAY) } YY_BREAK -case 57: +case 58: YY_RULE_SETUP #line 271 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HTTP_NOTLS_DOWNSTREAM) } YY_BREAK -case 58: +case 59: YY_RULE_SETUP #line 272 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_QUIC_PORT) } YY_BREAK -case 59: +case 60: YY_RULE_SETUP #line 273 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_QUIC_SIZE) } YY_BREAK -case 60: +case 61: YY_RULE_SETUP #line 274 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_USE_SYSTEMD) } YY_BREAK -case 61: +case 62: YY_RULE_SETUP #line 275 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DO_DAEMONIZE) } YY_BREAK -case 62: +case 63: YY_RULE_SETUP #line 276 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_INTERFACE) } YY_BREAK -case 63: +case 64: YY_RULE_SETUP #line 277 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_INTERFACE) } YY_BREAK -case 64: +case 65: YY_RULE_SETUP #line 278 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_OUTGOING_INTERFACE) } YY_BREAK -case 65: +case 66: YY_RULE_SETUP #line 279 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_INTERFACE_AUTOMATIC) } YY_BREAK -case 66: +case 67: YY_RULE_SETUP #line 280 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_INTERFACE_AUTOMATIC_PORTS) } YY_BREAK -case 67: +case 68: YY_RULE_SETUP #line 281 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_SO_RCVBUF) } YY_BREAK -case 68: +case 69: YY_RULE_SETUP #line 282 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_SO_SNDBUF) } YY_BREAK -case 69: +case 70: YY_RULE_SETUP #line 283 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_SO_REUSEPORT) } YY_BREAK -case 70: +case 71: YY_RULE_SETUP #line 284 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_IP_TRANSPARENT) } YY_BREAK -case 71: +case 72: YY_RULE_SETUP #line 285 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_IP_FREEBIND) } YY_BREAK -case 72: +case 73: YY_RULE_SETUP #line 286 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_IP_DSCP) } YY_BREAK -case 73: +case 74: YY_RULE_SETUP #line 287 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CHROOT) } YY_BREAK -case 74: +case 75: YY_RULE_SETUP #line 288 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_USERNAME) } YY_BREAK -case 75: +case 76: YY_RULE_SETUP #line 289 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DIRECTORY) } YY_BREAK -case 76: +case 77: YY_RULE_SETUP #line 290 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_LOGFILE) } YY_BREAK -case 77: +case 78: YY_RULE_SETUP #line 291 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_PIDFILE) } YY_BREAK -case 78: +case 79: YY_RULE_SETUP #line 292 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_ROOT_HINTS) } YY_BREAK -case 79: +case 80: YY_RULE_SETUP #line 293 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_STREAM_WAIT_SIZE) } YY_BREAK -case 80: +case 81: YY_RULE_SETUP #line 294 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_EDNS_BUFFER_SIZE) } YY_BREAK -case 81: +case 82: YY_RULE_SETUP #line 295 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_MSG_BUFFER_SIZE) } YY_BREAK -case 82: +case 83: YY_RULE_SETUP #line 296 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_MSG_CACHE_SIZE) } YY_BREAK -case 83: +case 84: YY_RULE_SETUP #line 297 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_MSG_CACHE_SLABS) } YY_BREAK -case 84: +case 85: YY_RULE_SETUP #line 298 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_RRSET_CACHE_SIZE) } YY_BREAK -case 85: +case 86: YY_RULE_SETUP #line 299 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_RRSET_CACHE_SLABS) } YY_BREAK -case 86: +case 87: YY_RULE_SETUP #line 300 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHE_MAX_TTL) } YY_BREAK -case 87: +case 88: YY_RULE_SETUP #line 301 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHE_MAX_NEGATIVE_TTL) } YY_BREAK -case 88: +case 89: YY_RULE_SETUP #line 302 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHE_MIN_NEGATIVE_TTL) } YY_BREAK -case 89: +case 90: YY_RULE_SETUP #line 303 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHE_MIN_TTL) } YY_BREAK -case 90: +case 91: YY_RULE_SETUP #line 304 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_INFRA_HOST_TTL) } YY_BREAK -case 91: +case 92: YY_RULE_SETUP #line 305 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_INFRA_LAME_TTL) } YY_BREAK -case 92: +case 93: YY_RULE_SETUP #line 306 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_INFRA_CACHE_SLABS) } YY_BREAK -case 93: +case 94: YY_RULE_SETUP #line 307 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_INFRA_CACHE_NUMHOSTS) } YY_BREAK -case 94: +case 95: YY_RULE_SETUP #line 308 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_INFRA_CACHE_LAME_SIZE) } YY_BREAK -case 95: +case 96: YY_RULE_SETUP #line 309 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_INFRA_CACHE_MIN_RTT) } YY_BREAK -case 96: +case 97: YY_RULE_SETUP #line 310 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_INFRA_CACHE_MAX_RTT) } YY_BREAK -case 97: +case 98: YY_RULE_SETUP #line 311 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_INFRA_KEEP_PROBING) } YY_BREAK -case 98: +case 99: YY_RULE_SETUP #line 312 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_NUM_QUERIES_PER_THREAD) } YY_BREAK -case 99: +case 100: YY_RULE_SETUP #line 313 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_JOSTLE_TIMEOUT) } YY_BREAK -case 100: +case 101: YY_RULE_SETUP #line 314 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DELAY_CLOSE) } YY_BREAK -case 101: +case 102: YY_RULE_SETUP #line 315 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_UDP_CONNECT) } YY_BREAK -case 102: +case 103: YY_RULE_SETUP #line 316 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TARGET_FETCH_POLICY) } YY_BREAK -case 103: +case 104: YY_RULE_SETUP #line 317 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HARDEN_SHORT_BUFSIZE) } YY_BREAK -case 104: +case 105: YY_RULE_SETUP #line 318 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HARDEN_LARGE_QUERIES) } YY_BREAK -case 105: +case 106: YY_RULE_SETUP #line 319 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HARDEN_GLUE) } YY_BREAK -case 106: +case 107: YY_RULE_SETUP #line 320 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HARDEN_UNVERIFIED_GLUE) } YY_BREAK -case 107: +case 108: YY_RULE_SETUP #line 321 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HARDEN_DNSSEC_STRIPPED) } YY_BREAK -case 108: +case 109: YY_RULE_SETUP #line 322 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HARDEN_BELOW_NXDOMAIN) } YY_BREAK -case 109: +case 110: YY_RULE_SETUP #line 323 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HARDEN_REFERRAL_PATH) } YY_BREAK -case 110: +case 111: YY_RULE_SETUP #line 324 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HARDEN_ALGO_DOWNGRADE) } YY_BREAK -case 111: +case 112: YY_RULE_SETUP #line 325 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HARDEN_UNKNOWN_ADDITIONAL) } YY_BREAK -case 112: +case 113: YY_RULE_SETUP #line 326 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_USE_CAPS_FOR_ID) } YY_BREAK -case 113: +case 114: YY_RULE_SETUP #line 327 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CAPS_WHITELIST) } YY_BREAK -case 114: +case 115: YY_RULE_SETUP #line 328 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CAPS_WHITELIST) } YY_BREAK -case 115: +case 116: YY_RULE_SETUP #line 329 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_UNWANTED_REPLY_THRESHOLD) } YY_BREAK -case 116: +case 117: YY_RULE_SETUP #line 330 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_PRIVATE_ADDRESS) } YY_BREAK -case 117: +case 118: YY_RULE_SETUP #line 331 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_PRIVATE_DOMAIN) } YY_BREAK -case 118: +case 119: YY_RULE_SETUP #line 332 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_PREFETCH_KEY) } YY_BREAK -case 119: +case 120: YY_RULE_SETUP #line 333 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_PREFETCH) } YY_BREAK -case 120: +case 121: YY_RULE_SETUP #line 334 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DENY_ANY) } YY_BREAK -case 121: +case 122: YY_RULE_SETUP #line 335 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(0, VAR_STUB_ZONE) } YY_BREAK -case 122: +case 123: YY_RULE_SETUP #line 336 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_NAME) } YY_BREAK -case 123: +case 124: YY_RULE_SETUP #line 337 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_STUB_ADDR) } YY_BREAK -case 124: +case 125: YY_RULE_SETUP #line 338 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_STUB_HOST) } YY_BREAK -case 125: +case 126: YY_RULE_SETUP #line 339 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_STUB_PRIME) } YY_BREAK -case 126: +case 127: YY_RULE_SETUP #line 340 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_STUB_FIRST) } YY_BREAK -case 127: +case 128: YY_RULE_SETUP #line 341 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_STUB_NO_CACHE) } YY_BREAK -case 128: +case 129: YY_RULE_SETUP #line 342 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_STUB_SSL_UPSTREAM) } YY_BREAK -case 129: +case 130: YY_RULE_SETUP #line 343 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_STUB_SSL_UPSTREAM) } YY_BREAK -case 130: +case 131: YY_RULE_SETUP #line 344 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_STUB_TCP_UPSTREAM) } YY_BREAK -case 131: +case 132: YY_RULE_SETUP #line 345 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(0, VAR_FORWARD_ZONE) } YY_BREAK -case 132: +case 133: YY_RULE_SETUP #line 346 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_FORWARD_ADDR) } YY_BREAK -case 133: +case 134: YY_RULE_SETUP #line 347 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_FORWARD_HOST) } YY_BREAK -case 134: +case 135: YY_RULE_SETUP #line 348 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_FORWARD_FIRST) } YY_BREAK -case 135: +case 136: YY_RULE_SETUP #line 349 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_FORWARD_NO_CACHE) } YY_BREAK -case 136: +case 137: YY_RULE_SETUP #line 350 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_FORWARD_SSL_UPSTREAM) } YY_BREAK -case 137: +case 138: YY_RULE_SETUP #line 351 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_FORWARD_SSL_UPSTREAM) } YY_BREAK -case 138: +case 139: YY_RULE_SETUP #line 352 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_FORWARD_TCP_UPSTREAM) } YY_BREAK -case 139: +case 140: YY_RULE_SETUP #line 353 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(0, VAR_AUTH_ZONE) } YY_BREAK -case 140: +case 141: YY_RULE_SETUP #line 354 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(0, VAR_RPZ) } YY_BREAK -case 141: +case 142: YY_RULE_SETUP #line 355 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TAGS) } YY_BREAK -case 142: +case 143: YY_RULE_SETUP #line 356 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_RPZ_ACTION_OVERRIDE) } YY_BREAK -case 143: +case 144: YY_RULE_SETUP #line 357 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_RPZ_CNAME_OVERRIDE) } YY_BREAK -case 144: +case 145: YY_RULE_SETUP #line 358 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_RPZ_LOG) } YY_BREAK -case 145: +case 146: YY_RULE_SETUP #line 359 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_RPZ_LOG_NAME) } YY_BREAK -case 146: +case 147: YY_RULE_SETUP #line 360 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_RPZ_SIGNAL_NXDOMAIN_RA) } YY_BREAK -case 147: +case 148: YY_RULE_SETUP #line 361 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_ZONEFILE) } YY_BREAK -case 148: +case 149: YY_RULE_SETUP #line 362 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_MASTER) } YY_BREAK -case 149: +case 150: YY_RULE_SETUP #line 363 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_MASTER) } YY_BREAK -case 150: +case 151: YY_RULE_SETUP #line 364 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_URL) } YY_BREAK -case 151: +case 152: YY_RULE_SETUP #line 365 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_ALLOW_NOTIFY) } YY_BREAK -case 152: +case 153: YY_RULE_SETUP #line 366 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_FOR_DOWNSTREAM) } YY_BREAK -case 153: +case 154: YY_RULE_SETUP #line 367 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_FOR_UPSTREAM) } YY_BREAK -case 154: +case 155: YY_RULE_SETUP #line 368 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_FALLBACK_ENABLED) } YY_BREAK -case 155: +case 156: YY_RULE_SETUP #line 369 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(0, VAR_VIEW) } YY_BREAK -case 156: +case 157: YY_RULE_SETUP #line 370 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_VIEW_FIRST) } YY_BREAK -case 157: +case 158: YY_RULE_SETUP #line 371 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DO_NOT_QUERY_ADDRESS) } YY_BREAK -case 158: +case 159: YY_RULE_SETUP #line 372 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DO_NOT_QUERY_LOCALHOST) } YY_BREAK -case 159: +case 160: YY_RULE_SETUP #line 373 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(2, VAR_ACCESS_CONTROL) } YY_BREAK -case 160: +case 161: YY_RULE_SETUP #line 374 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(2, VAR_INTERFACE_ACTION) } YY_BREAK -case 161: +case 162: YY_RULE_SETUP #line 375 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_SEND_CLIENT_SUBNET) } YY_BREAK -case 162: +case 163: YY_RULE_SETUP #line 376 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CLIENT_SUBNET_ZONE) } YY_BREAK -case 163: +case 164: YY_RULE_SETUP #line 377 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CLIENT_SUBNET_ALWAYS_FORWARD) } YY_BREAK -case 164: +case 165: YY_RULE_SETUP #line 378 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CLIENT_SUBNET_OPCODE) } YY_BREAK -case 165: +case 166: YY_RULE_SETUP #line 379 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_MAX_CLIENT_SUBNET_IPV4) } YY_BREAK -case 166: +case 167: YY_RULE_SETUP #line 380 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_MAX_CLIENT_SUBNET_IPV6) } YY_BREAK -case 167: +case 168: YY_RULE_SETUP #line 381 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_MIN_CLIENT_SUBNET_IPV4) } YY_BREAK -case 168: +case 169: YY_RULE_SETUP #line 382 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_MIN_CLIENT_SUBNET_IPV6) } YY_BREAK -case 169: +case 170: YY_RULE_SETUP #line 383 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_MAX_ECS_TREE_SIZE_IPV4) } YY_BREAK -case 170: +case 171: YY_RULE_SETUP #line 384 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_MAX_ECS_TREE_SIZE_IPV6) } YY_BREAK -case 171: +case 172: YY_RULE_SETUP #line 385 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HIDE_IDENTITY) } YY_BREAK -case 172: +case 173: YY_RULE_SETUP #line 386 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HIDE_VERSION) } YY_BREAK -case 173: +case 174: YY_RULE_SETUP #line 387 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HIDE_TRUSTANCHOR) } YY_BREAK -case 174: +case 175: YY_RULE_SETUP #line 388 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HIDE_HTTP_USER_AGENT) } YY_BREAK -case 175: +case 176: YY_RULE_SETUP #line 389 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_IDENTITY) } YY_BREAK -case 176: +case 177: YY_RULE_SETUP #line 390 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_VERSION) } YY_BREAK -case 177: +case 178: YY_RULE_SETUP #line 391 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_HTTP_USER_AGENT) } YY_BREAK -case 178: +case 179: YY_RULE_SETUP #line 392 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_MODULE_CONF) } YY_BREAK -case 179: +case 180: YY_RULE_SETUP #line 393 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DLV_ANCHOR) } YY_BREAK -case 180: +case 181: YY_RULE_SETUP #line 394 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DLV_ANCHOR_FILE) } YY_BREAK -case 181: +case 182: YY_RULE_SETUP #line 395 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TRUST_ANCHOR_FILE) } YY_BREAK -case 182: +case 183: YY_RULE_SETUP #line 396 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_AUTO_TRUST_ANCHOR_FILE) } YY_BREAK -case 183: +case 184: YY_RULE_SETUP #line 397 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TRUSTED_KEYS_FILE) } YY_BREAK -case 184: +case 185: YY_RULE_SETUP #line 398 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TRUST_ANCHOR) } YY_BREAK -case 185: +case 186: YY_RULE_SETUP #line 399 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_TRUST_ANCHOR_SIGNALING) } YY_BREAK -case 186: +case 187: YY_RULE_SETUP #line 400 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_ROOT_KEY_SENTINEL) } YY_BREAK -case 187: +case 188: YY_RULE_SETUP #line 401 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_VAL_OVERRIDE_DATE) } YY_BREAK -case 188: +case 189: YY_RULE_SETUP #line 402 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_VAL_SIG_SKEW_MIN) } YY_BREAK -case 189: +case 190: YY_RULE_SETUP #line 403 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_VAL_SIG_SKEW_MAX) } YY_BREAK -case 190: +case 191: YY_RULE_SETUP #line 404 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_VAL_MAX_RESTART) } YY_BREAK -case 191: +case 192: YY_RULE_SETUP #line 405 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_BOGUS_TTL) } YY_BREAK -case 192: +case 193: YY_RULE_SETUP #line 406 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_VAL_CLEAN_ADDITIONAL) } YY_BREAK -case 193: +case 194: YY_RULE_SETUP #line 407 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_VAL_PERMISSIVE_MODE) } YY_BREAK -case 194: +case 195: YY_RULE_SETUP #line 408 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_AGGRESSIVE_NSEC) } YY_BREAK -case 195: +case 196: YY_RULE_SETUP #line 409 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_IGNORE_CD_FLAG) } YY_BREAK -case 196: +case 197: YY_RULE_SETUP #line 410 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DISABLE_EDNS_DO) } YY_BREAK -case 197: +case 198: YY_RULE_SETUP #line 411 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_SERVE_EXPIRED) } YY_BREAK -case 198: +case 199: YY_RULE_SETUP #line 412 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_SERVE_EXPIRED_TTL) } YY_BREAK -case 199: +case 200: YY_RULE_SETUP #line 413 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_SERVE_EXPIRED_TTL_RESET) } YY_BREAK -case 200: +case 201: YY_RULE_SETUP #line 414 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_SERVE_EXPIRED_REPLY_TTL) } YY_BREAK -case 201: +case 202: YY_RULE_SETUP #line 415 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_SERVE_EXPIRED_CLIENT_TIMEOUT) } YY_BREAK -case 202: +case 203: YY_RULE_SETUP #line 416 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_EDE_SERVE_EXPIRED) } YY_BREAK -case 203: +case 204: YY_RULE_SETUP #line 417 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_SERVE_ORIGINAL_TTL) } YY_BREAK -case 204: +case 205: YY_RULE_SETUP #line 418 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_FAKE_DSA) } YY_BREAK -case 205: +case 206: YY_RULE_SETUP #line 419 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_FAKE_SHA1) } YY_BREAK -case 206: +case 207: YY_RULE_SETUP #line 420 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_VAL_LOG_LEVEL) } YY_BREAK -case 207: +case 208: YY_RULE_SETUP #line 421 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_KEY_CACHE_SIZE) } YY_BREAK -case 208: +case 209: YY_RULE_SETUP #line 422 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_KEY_CACHE_SLABS) } YY_BREAK -case 209: +case 210: YY_RULE_SETUP #line 423 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_NEG_CACHE_SIZE) } YY_BREAK -case 210: +case 211: YY_RULE_SETUP #line 424 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_VAL_NSEC3_KEYSIZE_ITERATIONS) } YY_BREAK -case 211: +case 212: YY_RULE_SETUP #line 426 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_ZONEMD_PERMISSIVE_MODE) } YY_BREAK -case 212: +case 213: YY_RULE_SETUP #line 427 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_ZONEMD_CHECK) } YY_BREAK -case 213: +case 214: YY_RULE_SETUP #line 428 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_ZONEMD_REJECT_ABSENCE) } YY_BREAK -case 214: +case 215: YY_RULE_SETUP #line 429 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_ADD_HOLDDOWN) } YY_BREAK -case 215: +case 216: YY_RULE_SETUP #line 430 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DEL_HOLDDOWN) } YY_BREAK -case 216: +case 217: YY_RULE_SETUP #line 431 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_KEEP_MISSING) } YY_BREAK -case 217: +case 218: YY_RULE_SETUP #line 432 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_PERMIT_SMALL_HOLDDOWN) } YY_BREAK -case 218: +case 219: YY_RULE_SETUP #line 433 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_USE_SYSLOG) } YY_BREAK -case 219: +case 220: YY_RULE_SETUP #line 434 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_LOG_IDENTITY) } YY_BREAK -case 220: +case 221: YY_RULE_SETUP #line 435 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_LOG_TIME_ASCII) } YY_BREAK -case 221: +case 222: YY_RULE_SETUP #line 436 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_LOG_TIME_ISO) } YY_BREAK -case 222: +case 223: YY_RULE_SETUP #line 437 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_LOG_QUERIES) } YY_BREAK -case 223: +case 224: YY_RULE_SETUP #line 438 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_LOG_REPLIES) } YY_BREAK -case 224: +case 225: YY_RULE_SETUP #line 439 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_LOG_TAG_QUERYREPLY) } YY_BREAK -case 225: +case 226: YY_RULE_SETUP #line 440 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_LOG_LOCAL_ACTIONS) } YY_BREAK -case 226: +case 227: YY_RULE_SETUP #line 441 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_LOG_SERVFAIL) } YY_BREAK -case 227: +case 228: YY_RULE_SETUP #line 442 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_LOG_DESTADDR) } YY_BREAK -case 228: +case 229: YY_RULE_SETUP #line 443 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(2, VAR_LOCAL_ZONE) } +{ YDVAR(1, VAR_LOG_THREAD_ID) } YY_BREAK -case 229: +case 230: YY_RULE_SETUP #line 444 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_LOCAL_DATA) } +{ YDVAR(2, VAR_LOCAL_ZONE) } YY_BREAK -case 230: +case 231: YY_RULE_SETUP #line 445 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_LOCAL_DATA_PTR) } +{ YDVAR(1, VAR_LOCAL_DATA) } YY_BREAK -case 231: +case 232: YY_RULE_SETUP #line 446 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_UNBLOCK_LAN_ZONES) } +{ YDVAR(1, VAR_LOCAL_DATA_PTR) } YY_BREAK -case 232: +case 233: YY_RULE_SETUP #line 447 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_INSECURE_LAN_ZONES) } +{ YDVAR(1, VAR_UNBLOCK_LAN_ZONES) } YY_BREAK -case 233: +case 234: YY_RULE_SETUP #line 448 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_STATISTICS_INTERVAL) } +{ YDVAR(1, VAR_INSECURE_LAN_ZONES) } YY_BREAK -case 234: +case 235: YY_RULE_SETUP #line 449 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_STATISTICS_CUMULATIVE) } +{ YDVAR(1, VAR_STATISTICS_INTERVAL) } YY_BREAK -case 235: +case 236: YY_RULE_SETUP #line 450 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_EXTENDED_STATISTICS) } +{ YDVAR(1, VAR_STATISTICS_CUMULATIVE) } YY_BREAK -case 236: +case 237: YY_RULE_SETUP #line 451 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_STATISTICS_INHIBIT_ZERO) } +{ YDVAR(1, VAR_EXTENDED_STATISTICS) } YY_BREAK -case 237: +case 238: YY_RULE_SETUP #line 452 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_SHM_ENABLE) } +{ YDVAR(1, VAR_STATISTICS_INHIBIT_ZERO) } YY_BREAK -case 238: +case 239: YY_RULE_SETUP #line 453 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_SHM_KEY) } +{ YDVAR(1, VAR_SHM_ENABLE) } YY_BREAK -case 239: +case 240: YY_RULE_SETUP #line 454 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(0, VAR_REMOTE_CONTROL) } +{ YDVAR(1, VAR_SHM_KEY) } YY_BREAK -case 240: +case 241: YY_RULE_SETUP #line 455 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_CONTROL_ENABLE) } +{ YDVAR(0, VAR_REMOTE_CONTROL) } YY_BREAK -case 241: +case 242: YY_RULE_SETUP #line 456 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_CONTROL_INTERFACE) } +{ YDVAR(1, VAR_CONTROL_ENABLE) } YY_BREAK -case 242: +case 243: YY_RULE_SETUP #line 457 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_CONTROL_PORT) } +{ YDVAR(1, VAR_CONTROL_INTERFACE) } YY_BREAK -case 243: +case 244: YY_RULE_SETUP #line 458 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_CONTROL_USE_CERT) } +{ YDVAR(1, VAR_CONTROL_PORT) } YY_BREAK -case 244: +case 245: YY_RULE_SETUP #line 459 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_SERVER_KEY_FILE) } +{ YDVAR(1, VAR_CONTROL_USE_CERT) } YY_BREAK -case 245: +case 246: YY_RULE_SETUP #line 460 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_SERVER_CERT_FILE) } +{ YDVAR(1, VAR_SERVER_KEY_FILE) } YY_BREAK -case 246: +case 247: YY_RULE_SETUP #line 461 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_CONTROL_KEY_FILE) } +{ YDVAR(1, VAR_SERVER_CERT_FILE) } YY_BREAK -case 247: +case 248: YY_RULE_SETUP #line 462 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_CONTROL_CERT_FILE) } +{ YDVAR(1, VAR_CONTROL_KEY_FILE) } YY_BREAK -case 248: +case 249: YY_RULE_SETUP #line 463 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_PYTHON_SCRIPT) } +{ YDVAR(1, VAR_CONTROL_CERT_FILE) } YY_BREAK -case 249: +case 250: YY_RULE_SETUP #line 464 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(0, VAR_PYTHON) } +{ YDVAR(1, VAR_PYTHON_SCRIPT) } YY_BREAK -case 250: +case 251: YY_RULE_SETUP #line 465 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DYNLIB_FILE) } +{ YDVAR(0, VAR_PYTHON) } YY_BREAK -case 251: +case 252: YY_RULE_SETUP #line 466 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(0, VAR_DYNLIB) } +{ YDVAR(1, VAR_DYNLIB_FILE) } YY_BREAK -case 252: +case 253: YY_RULE_SETUP #line 467 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DOMAIN_INSECURE) } +{ YDVAR(0, VAR_DYNLIB) } YY_BREAK -case 253: +case 254: YY_RULE_SETUP #line 468 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_MINIMAL_RESPONSES) } +{ YDVAR(1, VAR_DOMAIN_INSECURE) } YY_BREAK -case 254: +case 255: YY_RULE_SETUP #line 469 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_RRSET_ROUNDROBIN) } +{ YDVAR(1, VAR_MINIMAL_RESPONSES) } YY_BREAK -case 255: +case 256: YY_RULE_SETUP #line 470 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_UNKNOWN_SERVER_TIME_LIMIT) } +{ YDVAR(1, VAR_RRSET_ROUNDROBIN) } YY_BREAK -case 256: +case 257: YY_RULE_SETUP #line 471 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DISCARD_TIMEOUT) } +{ YDVAR(1, VAR_UNKNOWN_SERVER_TIME_LIMIT) } YY_BREAK -case 257: +case 258: YY_RULE_SETUP #line 472 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_WAIT_LIMIT) } +{ YDVAR(1, VAR_DISCARD_TIMEOUT) } YY_BREAK -case 258: +case 259: YY_RULE_SETUP #line 473 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_WAIT_LIMIT_COOKIE) } +{ YDVAR(1, VAR_WAIT_LIMIT) } YY_BREAK -case 259: +case 260: YY_RULE_SETUP #line 474 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(2, VAR_WAIT_LIMIT_NETBLOCK) } +{ YDVAR(1, VAR_WAIT_LIMIT_COOKIE) } YY_BREAK -case 260: +case 261: YY_RULE_SETUP #line 475 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(2, VAR_WAIT_LIMIT_COOKIE_NETBLOCK) } +{ YDVAR(2, VAR_WAIT_LIMIT_NETBLOCK) } YY_BREAK -case 261: +case 262: YY_RULE_SETUP #line 476 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_MAX_UDP_SIZE) } +{ YDVAR(2, VAR_WAIT_LIMIT_COOKIE_NETBLOCK) } YY_BREAK -case 262: +case 263: YY_RULE_SETUP #line 477 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DNS64_PREFIX) } +{ YDVAR(1, VAR_MAX_UDP_SIZE) } YY_BREAK -case 263: +case 264: YY_RULE_SETUP #line 478 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DNS64_SYNTHALL) } +{ YDVAR(1, VAR_DNS64_PREFIX) } YY_BREAK -case 264: +case 265: YY_RULE_SETUP #line 479 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DNS64_IGNORE_AAAA) } +{ YDVAR(1, VAR_DNS64_SYNTHALL) } YY_BREAK -case 265: +case 266: YY_RULE_SETUP #line 480 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_NAT64_PREFIX) } +{ YDVAR(1, VAR_DNS64_IGNORE_AAAA) } YY_BREAK -case 266: +case 267: YY_RULE_SETUP #line 481 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DEFINE_TAG) } +{ YDVAR(1, VAR_NAT64_PREFIX) } YY_BREAK -case 267: +case 268: YY_RULE_SETUP #line 482 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(2, VAR_LOCAL_ZONE_TAG) } +{ YDVAR(1, VAR_DEFINE_TAG) } YY_BREAK -case 268: +case 269: YY_RULE_SETUP #line 483 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(2, VAR_ACCESS_CONTROL_TAG) } +{ YDVAR(2, VAR_LOCAL_ZONE_TAG) } YY_BREAK -case 269: +case 270: YY_RULE_SETUP #line 484 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(3, VAR_ACCESS_CONTROL_TAG_ACTION) } +{ YDVAR(2, VAR_ACCESS_CONTROL_TAG) } YY_BREAK -case 270: +case 271: YY_RULE_SETUP #line 485 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(3, VAR_ACCESS_CONTROL_TAG_DATA) } +{ YDVAR(3, VAR_ACCESS_CONTROL_TAG_ACTION) } YY_BREAK -case 271: +case 272: YY_RULE_SETUP #line 486 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(2, VAR_ACCESS_CONTROL_VIEW) } +{ YDVAR(3, VAR_ACCESS_CONTROL_TAG_DATA) } YY_BREAK -case 272: +case 273: YY_RULE_SETUP #line 487 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(2, VAR_INTERFACE_TAG) } +{ YDVAR(2, VAR_ACCESS_CONTROL_VIEW) } YY_BREAK -case 273: +case 274: YY_RULE_SETUP #line 488 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(3, VAR_INTERFACE_TAG_ACTION) } +{ YDVAR(2, VAR_INTERFACE_TAG) } YY_BREAK -case 274: +case 275: YY_RULE_SETUP #line 489 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(3, VAR_INTERFACE_TAG_DATA) } +{ YDVAR(3, VAR_INTERFACE_TAG_ACTION) } YY_BREAK -case 275: +case 276: YY_RULE_SETUP #line 490 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(2, VAR_INTERFACE_VIEW) } +{ YDVAR(3, VAR_INTERFACE_TAG_DATA) } YY_BREAK -case 276: +case 277: YY_RULE_SETUP #line 491 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(3, VAR_LOCAL_ZONE_OVERRIDE) } +{ YDVAR(2, VAR_INTERFACE_VIEW) } YY_BREAK -case 277: +case 278: YY_RULE_SETUP #line 492 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(0, VAR_DNSTAP) } +{ YDVAR(3, VAR_LOCAL_ZONE_OVERRIDE) } YY_BREAK -case 278: +case 279: YY_RULE_SETUP #line 493 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DNSTAP_ENABLE) } +{ YDVAR(0, VAR_DNSTAP) } YY_BREAK -case 279: +case 280: YY_RULE_SETUP #line 494 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DNSTAP_BIDIRECTIONAL) } +{ YDVAR(1, VAR_DNSTAP_ENABLE) } YY_BREAK -case 280: +case 281: YY_RULE_SETUP #line 495 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DNSTAP_SOCKET_PATH) } +{ YDVAR(1, VAR_DNSTAP_BIDIRECTIONAL) } YY_BREAK -case 281: +case 282: YY_RULE_SETUP #line 496 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DNSTAP_IP) } +{ YDVAR(1, VAR_DNSTAP_SOCKET_PATH) } YY_BREAK -case 282: +case 283: YY_RULE_SETUP #line 497 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DNSTAP_TLS) } +{ YDVAR(1, VAR_DNSTAP_IP) } YY_BREAK -case 283: +case 284: YY_RULE_SETUP #line 498 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DNSTAP_TLS_SERVER_NAME) } +{ YDVAR(1, VAR_DNSTAP_TLS) } YY_BREAK -case 284: +case 285: YY_RULE_SETUP #line 499 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DNSTAP_TLS_CERT_BUNDLE) } +{ YDVAR(1, VAR_DNSTAP_TLS_SERVER_NAME) } YY_BREAK -case 285: +case 286: YY_RULE_SETUP #line 500 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +{ YDVAR(1, VAR_DNSTAP_TLS_CERT_BUNDLE) } + YY_BREAK +case 287: +YY_RULE_SETUP +#line 501 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DNSTAP_TLS_CLIENT_KEY_FILE) } YY_BREAK -case 286: +case 288: YY_RULE_SETUP -#line 502 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 503 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DNSTAP_TLS_CLIENT_CERT_FILE) } YY_BREAK -case 287: +case 289: YY_RULE_SETUP -#line 504 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 505 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DNSTAP_SEND_IDENTITY) } YY_BREAK -case 288: +case 290: YY_RULE_SETUP -#line 505 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 506 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DNSTAP_SEND_VERSION) } YY_BREAK -case 289: +case 291: YY_RULE_SETUP -#line 506 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 507 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DNSTAP_IDENTITY) } YY_BREAK -case 290: +case 292: YY_RULE_SETUP -#line 507 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 508 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DNSTAP_VERSION) } YY_BREAK -case 291: +case 293: YY_RULE_SETUP -#line 508 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 509 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES) } YY_BREAK -case 292: +case 294: YY_RULE_SETUP -#line 510 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 511 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES) } YY_BREAK -case 293: +case 295: YY_RULE_SETUP -#line 512 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 513 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES) } YY_BREAK -case 294: +case 296: YY_RULE_SETUP -#line 514 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 515 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES) } YY_BREAK -case 295: +case 297: YY_RULE_SETUP -#line 516 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 517 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES) } YY_BREAK -case 296: +case 298: YY_RULE_SETUP -#line 518 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 519 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES) } YY_BREAK -case 297: -YY_RULE_SETUP -#line 520 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DNSTAP_SAMPLE_RATE) } - YY_BREAK -case 298: +case 299: YY_RULE_SETUP #line 521 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DISABLE_DNSSEC_LAME_CHECK) } +{ YDVAR(1, VAR_DNSTAP_SAMPLE_RATE) } YY_BREAK -case 299: +case 300: YY_RULE_SETUP #line 522 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_IP_RATELIMIT) } +{ YDVAR(1, VAR_DISABLE_DNSSEC_LAME_CHECK) } YY_BREAK -case 300: +case 301: YY_RULE_SETUP #line 523 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_IP_RATELIMIT_COOKIE) } +{ YDVAR(1, VAR_IP_RATELIMIT) } YY_BREAK -case 301: +case 302: YY_RULE_SETUP #line 524 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_RATELIMIT) } +{ YDVAR(1, VAR_IP_RATELIMIT_COOKIE) } YY_BREAK -case 302: +case 303: YY_RULE_SETUP #line 525 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_IP_RATELIMIT_SLABS) } +{ YDVAR(1, VAR_RATELIMIT) } YY_BREAK -case 303: +case 304: YY_RULE_SETUP #line 526 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_RATELIMIT_SLABS) } +{ YDVAR(1, VAR_IP_RATELIMIT_SLABS) } YY_BREAK -case 304: +case 305: YY_RULE_SETUP #line 527 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_IP_RATELIMIT_SIZE) } +{ YDVAR(1, VAR_RATELIMIT_SLABS) } YY_BREAK -case 305: +case 306: YY_RULE_SETUP #line 528 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_RATELIMIT_SIZE) } +{ YDVAR(1, VAR_IP_RATELIMIT_SIZE) } YY_BREAK -case 306: +case 307: YY_RULE_SETUP #line 529 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(2, VAR_RATELIMIT_FOR_DOMAIN) } +{ YDVAR(1, VAR_RATELIMIT_SIZE) } YY_BREAK -case 307: +case 308: YY_RULE_SETUP #line 530 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(2, VAR_RATELIMIT_BELOW_DOMAIN) } +{ YDVAR(2, VAR_RATELIMIT_FOR_DOMAIN) } YY_BREAK -case 308: +case 309: YY_RULE_SETUP #line 531 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_IP_RATELIMIT_FACTOR) } +{ YDVAR(2, VAR_RATELIMIT_BELOW_DOMAIN) } YY_BREAK -case 309: +case 310: YY_RULE_SETUP #line 532 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_RATELIMIT_FACTOR) } +{ YDVAR(1, VAR_IP_RATELIMIT_FACTOR) } YY_BREAK -case 310: +case 311: YY_RULE_SETUP #line 533 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_IP_RATELIMIT_BACKOFF) } +{ YDVAR(1, VAR_RATELIMIT_FACTOR) } YY_BREAK -case 311: +case 312: YY_RULE_SETUP #line 534 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_RATELIMIT_BACKOFF) } +{ YDVAR(1, VAR_IP_RATELIMIT_BACKOFF) } YY_BREAK -case 312: +case 313: YY_RULE_SETUP #line 535 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_OUTBOUND_MSG_RETRY) } +{ YDVAR(1, VAR_RATELIMIT_BACKOFF) } YY_BREAK -case 313: +case 314: YY_RULE_SETUP #line 536 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_MAX_SENT_COUNT) } +{ YDVAR(1, VAR_OUTBOUND_MSG_RETRY) } YY_BREAK -case 314: +case 315: YY_RULE_SETUP #line 537 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_MAX_QUERY_RESTARTS) } +{ YDVAR(1, VAR_MAX_SENT_COUNT) } YY_BREAK -case 315: +case 316: YY_RULE_SETUP #line 538 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_LOW_RTT) } +{ YDVAR(1, VAR_MAX_QUERY_RESTARTS) } YY_BREAK -case 316: +case 317: YY_RULE_SETUP #line 539 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_FAST_SERVER_NUM) } +{ YDVAR(1, VAR_LOW_RTT) } YY_BREAK -case 317: +case 318: YY_RULE_SETUP #line 540 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_FAST_SERVER_PERMIL) } +{ YDVAR(1, VAR_FAST_SERVER_NUM) } YY_BREAK -case 318: +case 319: YY_RULE_SETUP #line 541 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_FAST_SERVER_PERMIL) } YY_BREAK -case 319: +case 320: YY_RULE_SETUP #line 542 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_FAST_SERVER_PERMIL) } YY_BREAK -case 320: +case 321: YY_RULE_SETUP #line 543 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(2, VAR_RESPONSE_IP_TAG) } +{ YDVAR(1, VAR_FAST_SERVER_PERMIL) } YY_BREAK -case 321: +case 322: YY_RULE_SETUP #line 544 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(2, VAR_RESPONSE_IP) } +{ YDVAR(2, VAR_RESPONSE_IP_TAG) } YY_BREAK -case 322: +case 323: YY_RULE_SETUP #line 545 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(2, VAR_RESPONSE_IP_DATA) } +{ YDVAR(2, VAR_RESPONSE_IP) } YY_BREAK -case 323: +case 324: YY_RULE_SETUP #line 546 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(0, VAR_DNSCRYPT) } +{ YDVAR(2, VAR_RESPONSE_IP_DATA) } YY_BREAK -case 324: +case 325: YY_RULE_SETUP #line 547 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DNSCRYPT_ENABLE) } +{ YDVAR(0, VAR_DNSCRYPT) } YY_BREAK -case 325: +case 326: YY_RULE_SETUP #line 548 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DNSCRYPT_PORT) } +{ YDVAR(1, VAR_DNSCRYPT_ENABLE) } YY_BREAK -case 326: +case 327: YY_RULE_SETUP #line 549 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DNSCRYPT_PROVIDER) } +{ YDVAR(1, VAR_DNSCRYPT_PORT) } YY_BREAK -case 327: +case 328: YY_RULE_SETUP #line 550 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DNSCRYPT_SECRET_KEY) } +{ YDVAR(1, VAR_DNSCRYPT_PROVIDER) } YY_BREAK -case 328: +case 329: YY_RULE_SETUP #line 551 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DNSCRYPT_PROVIDER_CERT) } +{ YDVAR(1, VAR_DNSCRYPT_SECRET_KEY) } YY_BREAK -case 329: +case 330: YY_RULE_SETUP #line 552 "/usr/src/usr.sbin/unbound/util/configlexer.lex" -{ YDVAR(1, VAR_DNSCRYPT_PROVIDER_CERT_ROTATED) } +{ YDVAR(1, VAR_DNSCRYPT_PROVIDER_CERT) } YY_BREAK -case 330: +case 331: YY_RULE_SETUP #line 553 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +{ YDVAR(1, VAR_DNSCRYPT_PROVIDER_CERT_ROTATED) } + YY_BREAK +case 332: +YY_RULE_SETUP +#line 554 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE) } YY_BREAK -case 331: +case 333: YY_RULE_SETUP -#line 555 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 556 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS) } YY_BREAK -case 332: +case 334: YY_RULE_SETUP -#line 557 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 558 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DNSCRYPT_NONCE_CACHE_SIZE) } YY_BREAK -case 333: +case 335: YY_RULE_SETUP -#line 558 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 559 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DNSCRYPT_NONCE_CACHE_SLABS) } YY_BREAK -case 334: +case 336: YY_RULE_SETUP -#line 559 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 560 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_PAD_RESPONSES) } YY_BREAK -case 335: +case 337: YY_RULE_SETUP -#line 560 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 561 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_PAD_RESPONSES_BLOCK_SIZE) } YY_BREAK -case 336: +case 338: YY_RULE_SETUP -#line 561 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 562 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_PAD_QUERIES) } YY_BREAK -case 337: +case 339: YY_RULE_SETUP -#line 562 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 563 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_PAD_QUERIES_BLOCK_SIZE) } YY_BREAK -case 338: +case 340: YY_RULE_SETUP -#line 563 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 564 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_IPSECMOD_ENABLED) } YY_BREAK -case 339: +case 341: YY_RULE_SETUP -#line 564 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 565 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_IPSECMOD_IGNORE_BOGUS) } YY_BREAK -case 340: +case 342: YY_RULE_SETUP -#line 565 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 566 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_IPSECMOD_HOOK) } YY_BREAK -case 341: +case 343: YY_RULE_SETUP -#line 566 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 567 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_IPSECMOD_MAX_TTL) } YY_BREAK -case 342: +case 344: YY_RULE_SETUP -#line 567 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 568 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_IPSECMOD_WHITELIST) } YY_BREAK -case 343: +case 345: YY_RULE_SETUP -#line 568 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 569 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_IPSECMOD_WHITELIST) } YY_BREAK -case 344: +case 346: YY_RULE_SETUP -#line 569 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 570 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_IPSECMOD_STRICT) } YY_BREAK -case 345: +case 347: YY_RULE_SETUP -#line 570 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 571 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(0, VAR_CACHEDB) } YY_BREAK -case 346: +case 348: YY_RULE_SETUP -#line 571 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 572 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_BACKEND) } YY_BREAK -case 347: +case 349: YY_RULE_SETUP -#line 572 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 573 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_SECRETSEED) } YY_BREAK -case 348: +case 350: YY_RULE_SETUP -#line 573 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 574 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_NO_STORE) } YY_BREAK -case 349: +case 351: YY_RULE_SETUP -#line 574 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 575 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED) } YY_BREAK -case 350: +case 352: YY_RULE_SETUP -#line 575 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 576 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_REDISHOST) } YY_BREAK -case 351: +case 353: YY_RULE_SETUP -#line 576 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 577 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_REDISREPLICAHOST) } YY_BREAK -case 352: +case 354: YY_RULE_SETUP -#line 577 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 578 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_REDISPORT) } YY_BREAK -case 353: +case 355: YY_RULE_SETUP -#line 578 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 579 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_REDISREPLICAPORT) } YY_BREAK -case 354: +case 356: YY_RULE_SETUP -#line 579 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 580 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_REDISPATH) } YY_BREAK -case 355: +case 357: YY_RULE_SETUP -#line 580 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 581 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_REDISREPLICAPATH) } YY_BREAK -case 356: +case 358: YY_RULE_SETUP -#line 581 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 582 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_REDISPASSWORD) } YY_BREAK -case 357: +case 359: YY_RULE_SETUP -#line 582 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 583 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_REDISREPLICAPASSWORD) } YY_BREAK -case 358: +case 360: YY_RULE_SETUP -#line 583 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 584 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_REDISTIMEOUT) } YY_BREAK -case 359: +case 361: YY_RULE_SETUP -#line 584 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 585 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_REDISREPLICATIMEOUT) } YY_BREAK -case 360: +case 362: YY_RULE_SETUP -#line 585 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 586 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_REDISCOMMANDTIMEOUT) } YY_BREAK -case 361: +case 363: YY_RULE_SETUP -#line 586 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 587 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_REDISREPLICACOMMANDTIMEOUT) } YY_BREAK -case 362: +case 364: YY_RULE_SETUP -#line 587 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 588 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_REDISCONNECTTIMEOUT) } YY_BREAK -case 363: +case 365: YY_RULE_SETUP -#line 588 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 589 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_REDISREPLICACONNECTTIMEOUT) } YY_BREAK -case 364: +case 366: YY_RULE_SETUP -#line 589 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 590 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_REDISEXPIRERECORDS) } YY_BREAK -case 365: +case 367: YY_RULE_SETUP -#line 590 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 591 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_REDISLOGICALDB) } YY_BREAK -case 366: +case 368: YY_RULE_SETUP -#line 591 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 592 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_CACHEDB_REDISREPLICALOGICALDB) } YY_BREAK -case 367: +case 369: YY_RULE_SETUP -#line 592 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 593 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(0, VAR_IPSET) } YY_BREAK -case 368: +case 370: YY_RULE_SETUP -#line 593 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 594 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_IPSET_NAME_V4) } YY_BREAK -case 369: +case 371: YY_RULE_SETUP -#line 594 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 595 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_IPSET_NAME_V6) } YY_BREAK -case 370: +case 372: YY_RULE_SETUP -#line 595 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 596 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM) } YY_BREAK -case 371: +case 373: YY_RULE_SETUP -#line 596 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 597 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(2, VAR_TCP_CONNECTION_LIMIT) } YY_BREAK -case 372: +case 374: YY_RULE_SETUP -#line 597 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 598 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_ANSWER_COOKIE ) } YY_BREAK -case 373: +case 375: YY_RULE_SETUP -#line 598 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 599 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_COOKIE_SECRET) } YY_BREAK -case 374: +case 376: YY_RULE_SETUP -#line 599 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 600 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_COOKIE_SECRET_FILE) } YY_BREAK -case 375: +case 377: YY_RULE_SETUP -#line 600 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 601 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(2, VAR_EDNS_CLIENT_STRING) } YY_BREAK -case 376: +case 378: YY_RULE_SETUP -#line 601 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 602 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_EDNS_CLIENT_STRING_OPCODE) } YY_BREAK -case 377: +case 379: YY_RULE_SETUP -#line 602 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 603 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_NSID ) } YY_BREAK -case 378: +case 380: YY_RULE_SETUP -#line 603 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 604 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_EDE ) } YY_BREAK -case 379: +case 381: YY_RULE_SETUP -#line 604 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 605 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_DNS_ERROR_REPORTING ) } YY_BREAK -case 380: +case 382: YY_RULE_SETUP -#line 605 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 606 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_PROXY_PROTOCOL_PORT) } YY_BREAK -case 381: +case 383: YY_RULE_SETUP -#line 606 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 607 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_ITER_SCRUB_NS) } YY_BREAK -case 382: +case 384: YY_RULE_SETUP -#line 607 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 608 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_ITER_SCRUB_CNAME) } YY_BREAK -case 383: +case 385: YY_RULE_SETUP -#line 608 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 609 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +{ YDVAR(1, VAR_ITER_SCRUB_RRSIG) } + YY_BREAK +case 386: +YY_RULE_SETUP +#line 610 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { YDVAR(1, VAR_MAX_GLOBAL_QUOTA) } YY_BREAK -case 384: -/* rule 384 can match eol */ +case 387: YY_RULE_SETUP -#line 609 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 611 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +{ YDVAR(1, VAR_VAL_VALIDATION_ATTEMPTS) } + YY_BREAK +case 388: +YY_RULE_SETUP +#line 612 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +{ YDVAR(1, VAR_VAL_HASH_ATTEMPTS) } + YY_BREAK +case 389: +YY_RULE_SETUP +#line 613 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +{ YDVAR(1, VAR_MAX_TRANSFER_SIZE) } + YY_BREAK +case 390: +YY_RULE_SETUP +#line 614 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +{ YDVAR(1, VAR_MAX_TRANSFER_TIME) } + YY_BREAK +case 391: +YY_RULE_SETUP +#line 615 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +{ YDVAR(1, VAR_ITER_SCRUB_PROMISCUOUS) } + YY_BREAK +case 392: +/* rule 392 can match eol */ +YY_RULE_SETUP +#line 616 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("NL\n")); cfg_parser->line++; } YY_BREAK /* Quoted strings. Strip leading and ending quotes */ -case 385: +case 393: YY_RULE_SETUP -#line 612 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 619 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { BEGIN(quotedstring); LEXOUT(("QS ")); } YY_BREAK case YY_STATE_EOF(quotedstring): -#line 613 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 620 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { yyerror("EOF inside quoted string"); if(--num_args == 0) { BEGIN(INITIAL); } else { BEGIN(val); } } YY_BREAK -case 386: +case 394: YY_RULE_SETUP -#line 618 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 625 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("STR(%s) ", yytext)); yymore(); } YY_BREAK -case 387: -/* rule 387 can match eol */ +case 395: +/* rule 395 can match eol */ YY_RULE_SETUP -#line 619 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 626 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { yyerror("newline inside quoted string, no end \""); cfg_parser->line++; BEGIN(INITIAL); } YY_BREAK -case 388: +case 396: YY_RULE_SETUP -#line 621 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 628 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("QE ")); if(--num_args == 0) { BEGIN(INITIAL); } @@ -6043,34 +6148,34 @@ YY_RULE_SETUP } YY_BREAK /* Single Quoted strings. Strip leading and ending quotes */ -case 389: +case 397: YY_RULE_SETUP -#line 633 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 640 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { BEGIN(singlequotedstr); LEXOUT(("SQS ")); } YY_BREAK case YY_STATE_EOF(singlequotedstr): -#line 634 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 641 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { yyerror("EOF inside quoted string"); if(--num_args == 0) { BEGIN(INITIAL); } else { BEGIN(val); } } YY_BREAK -case 390: +case 398: YY_RULE_SETUP -#line 639 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 646 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("STR(%s) ", yytext)); yymore(); } YY_BREAK -case 391: -/* rule 391 can match eol */ +case 399: +/* rule 399 can match eol */ YY_RULE_SETUP -#line 640 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 647 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { yyerror("newline inside quoted string, no end '"); cfg_parser->line++; BEGIN(INITIAL); } YY_BREAK -case 392: +case 400: YY_RULE_SETUP -#line 642 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 649 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("SQE ")); if(--num_args == 0) { BEGIN(INITIAL); } @@ -6083,38 +6188,38 @@ YY_RULE_SETUP } YY_BREAK /* include: directive */ -case 393: +case 401: YY_RULE_SETUP -#line 654 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 661 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("v(%s) ", yytext)); inc_prev = YYSTATE; BEGIN(include); } YY_BREAK case YY_STATE_EOF(include): -#line 656 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 663 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { yyerror("EOF inside include directive"); BEGIN(inc_prev); } YY_BREAK -case 394: +case 402: YY_RULE_SETUP -#line 660 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 667 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("ISP ")); /* ignore */ } YY_BREAK -case 395: -/* rule 395 can match eol */ +case 403: +/* rule 403 can match eol */ YY_RULE_SETUP -#line 661 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 668 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("NL\n")); cfg_parser->line++;} YY_BREAK -case 396: +case 404: YY_RULE_SETUP -#line 662 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 669 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("IQS ")); BEGIN(include_quoted); } YY_BREAK -case 397: +case 405: YY_RULE_SETUP -#line 663 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 670 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("Iunquotedstr(%s) ", yytext)); config_start_include_glob(yytext, 0); @@ -6122,27 +6227,27 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(include_quoted): -#line 668 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 675 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { yyerror("EOF inside quoted string"); BEGIN(inc_prev); } YY_BREAK -case 398: +case 406: YY_RULE_SETUP -#line 672 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 679 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("ISTR(%s) ", yytext)); yymore(); } YY_BREAK -case 399: -/* rule 399 can match eol */ +case 407: +/* rule 407 can match eol */ YY_RULE_SETUP -#line 673 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 680 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { yyerror("newline before \" in include name"); cfg_parser->line++; BEGIN(inc_prev); } YY_BREAK -case 400: +case 408: YY_RULE_SETUP -#line 675 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 682 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("IQE ")); yytext[yyleng - 1] = '\0'; @@ -6152,7 +6257,7 @@ YY_RULE_SETUP YY_BREAK case YY_STATE_EOF(INITIAL): case YY_STATE_EOF(val): -#line 681 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 688 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("LEXEOF ")); yy_set_bol(1); /* Set beginning of line, so "^" rules match. */ @@ -6167,39 +6272,39 @@ case YY_STATE_EOF(val): } YY_BREAK /* include-toplevel: directive */ -case 401: +case 409: YY_RULE_SETUP -#line 695 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 702 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("v(%s) ", yytext)); inc_prev = YYSTATE; BEGIN(include_toplevel); } YY_BREAK case YY_STATE_EOF(include_toplevel): -#line 698 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 705 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { yyerror("EOF inside include_toplevel directive"); BEGIN(inc_prev); } YY_BREAK -case 402: +case 410: YY_RULE_SETUP -#line 702 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 709 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("ITSP ")); /* ignore */ } YY_BREAK -case 403: -/* rule 403 can match eol */ +case 411: +/* rule 411 can match eol */ YY_RULE_SETUP -#line 703 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 710 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("NL\n")); cfg_parser->line++; } YY_BREAK -case 404: +case 412: YY_RULE_SETUP -#line 704 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 711 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("ITQS ")); BEGIN(include_toplevel_quoted); } YY_BREAK -case 405: +case 413: YY_RULE_SETUP -#line 705 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 712 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("ITunquotedstr(%s) ", yytext)); config_start_include_glob(yytext, 1); @@ -6208,29 +6313,29 @@ YY_RULE_SETUP } YY_BREAK case YY_STATE_EOF(include_toplevel_quoted): -#line 711 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 718 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { yyerror("EOF inside quoted string"); BEGIN(inc_prev); } YY_BREAK -case 406: +case 414: YY_RULE_SETUP -#line 715 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 722 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("ITSTR(%s) ", yytext)); yymore(); } YY_BREAK -case 407: -/* rule 407 can match eol */ +case 415: +/* rule 415 can match eol */ YY_RULE_SETUP -#line 716 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 723 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { yyerror("newline before \" in include name"); cfg_parser->line++; BEGIN(inc_prev); } YY_BREAK -case 408: +case 416: YY_RULE_SETUP -#line 720 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 727 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("ITQE ")); yytext[yyleng - 1] = '\0'; @@ -6239,33 +6344,33 @@ YY_RULE_SETUP return (VAR_FORCE_TOPLEVEL); } YY_BREAK -case 409: +case 417: YY_RULE_SETUP -#line 728 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 735 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { LEXOUT(("unquotedstr(%s) ", yytext)); if(--num_args == 0) { BEGIN(INITIAL); } yylval.str = strdup(yytext); return STRING_ARG; } YY_BREAK -case 410: +case 418: YY_RULE_SETUP -#line 732 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 739 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { ub_c_error_msg("unknown keyword '%s'", yytext); } YY_BREAK -case 411: +case 419: YY_RULE_SETUP -#line 736 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 743 "/usr/src/usr.sbin/unbound/util/configlexer.lex" { ub_c_error_msg("stray '%s'", yytext); } YY_BREAK -case 412: +case 420: YY_RULE_SETUP -#line 740 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 747 "/usr/src/usr.sbin/unbound/util/configlexer.lex" ECHO; YY_BREAK -#line 6267 "" +#line 6372 "" case YY_END_OF_BUFFER: { @@ -6558,7 +6663,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 >= 4118 ) + if ( yy_current_state >= 4207 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; @@ -6586,11 +6691,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 >= 4118 ) + if ( yy_current_state >= 4207 ) yy_c = yy_meta[(unsigned int) yy_c]; } yy_current_state = yy_nxt[yy_base[yy_current_state] + (unsigned int) yy_c]; - yy_is_jam = (yy_current_state == 4117); + yy_is_jam = (yy_current_state == 4206); return yy_is_jam ? 0 : yy_current_state; } @@ -7223,7 +7328,7 @@ void yyfree (void * ptr ) #define YYTABLES_NAME "yytables" -#line 740 "/usr/src/usr.sbin/unbound/util/configlexer.lex" +#line 747 "/usr/src/usr.sbin/unbound/util/configlexer.lex" Index: sbin/unwind/libunbound/util/configlexer.lex =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/configlexer.lex,v diff -u -p -r1.20 configlexer.lex --- sbin/unwind/libunbound/util/configlexer.lex 14 Sep 2025 15:16:53 -0000 1.20 +++ sbin/unwind/libunbound/util/configlexer.lex 21 Sep 2026 16:28:28 -0000 @@ -13,7 +13,6 @@ #pragma GCC diagnostic ignored "-Wsign-compare" #endif -#include #include #ifdef HAVE_GLOB_H # include @@ -262,6 +261,7 @@ tls-session-ticket-keys{COLON} { YDVAR(1 tls-ciphers{COLON} { YDVAR(1, VAR_TLS_CIPHERS) } tls-ciphersuites{COLON} { YDVAR(1, VAR_TLS_CIPHERSUITES) } tls-use-sni{COLON} { YDVAR(1, VAR_TLS_USE_SNI) } +tls-protocols{COLON} { YDVAR(1, VAR_TLS_PROTOCOLS) } https-port{COLON} { YDVAR(1, VAR_HTTPS_PORT) } http-endpoint{COLON} { YDVAR(1, VAR_HTTP_ENDPOINT) } http-max-streams{COLON} { YDVAR(1, VAR_HTTP_MAX_STREAMS) } @@ -440,6 +440,7 @@ log-tag-queryreply{COLON} { YDVAR(1, VAR log-local-actions{COLON} { YDVAR(1, VAR_LOG_LOCAL_ACTIONS) } log-servfail{COLON} { YDVAR(1, VAR_LOG_SERVFAIL) } log-destaddr{COLON} { YDVAR(1, VAR_LOG_DESTADDR) } +log-thread-id{COLON} { YDVAR(1, VAR_LOG_THREAD_ID) } local-zone{COLON} { YDVAR(2, VAR_LOCAL_ZONE) } local-data{COLON} { YDVAR(1, VAR_LOCAL_DATA) } local-data-ptr{COLON} { YDVAR(1, VAR_LOCAL_DATA_PTR) } @@ -605,7 +606,13 @@ dns-error-reporting{COLON} { YDVAR(1, VA 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) } +iter-scrub-rrsig{COLON} { YDVAR(1, VAR_ITER_SCRUB_RRSIG) } max-global-quota{COLON} { YDVAR(1, VAR_MAX_GLOBAL_QUOTA) } +val-validation-attempts{COLON} { YDVAR(1, VAR_VAL_VALIDATION_ATTEMPTS) } +val-hash-attempts{COLON} { YDVAR(1, VAR_VAL_HASH_ATTEMPTS) } +max-transfer-size{COLON} { YDVAR(1, VAR_MAX_TRANSFER_SIZE) } +max-transfer-time{COLON} { YDVAR(1, VAR_MAX_TRANSFER_TIME) } +iter-scrub-promiscuous{COLON} { YDVAR(1, VAR_ITER_SCRUB_PROMISCUOUS) } {NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; } /* Quoted strings. Strip leading and ending quotes */ Index: sbin/unwind/libunbound/util/configparser.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/configparser.h,v diff -u -p -r1.19 configparser.h --- sbin/unwind/libunbound/util/configparser.h 14 Sep 2025 15:16:53 -0000 1.19 +++ sbin/unwind/libunbound/util/configparser.h 21 Sep 2026 16:28:28 -0000 @@ -330,48 +330,56 @@ #define VAR_TLS_CIPHERS 586 #define VAR_TLS_CIPHERSUITES 587 #define VAR_TLS_USE_SNI 588 -#define VAR_IPSET 589 -#define VAR_IPSET_NAME_V4 590 -#define VAR_IPSET_NAME_V6 591 -#define VAR_TLS_SESSION_TICKET_KEYS 592 -#define VAR_RPZ 593 -#define VAR_TAGS 594 -#define VAR_RPZ_ACTION_OVERRIDE 595 -#define VAR_RPZ_CNAME_OVERRIDE 596 -#define VAR_RPZ_LOG 597 -#define VAR_RPZ_LOG_NAME 598 -#define VAR_DYNLIB 599 -#define VAR_DYNLIB_FILE 600 -#define VAR_EDNS_CLIENT_STRING 601 -#define VAR_EDNS_CLIENT_STRING_OPCODE 602 -#define VAR_NSID 603 -#define VAR_ZONEMD_PERMISSIVE_MODE 604 -#define VAR_ZONEMD_CHECK 605 -#define VAR_ZONEMD_REJECT_ABSENCE 606 -#define VAR_RPZ_SIGNAL_NXDOMAIN_RA 607 -#define VAR_INTERFACE_AUTOMATIC_PORTS 608 -#define VAR_EDE 609 -#define VAR_DNS_ERROR_REPORTING 610 -#define VAR_INTERFACE_ACTION 611 -#define VAR_INTERFACE_VIEW 612 -#define VAR_INTERFACE_TAG 613 -#define VAR_INTERFACE_TAG_ACTION 614 -#define VAR_INTERFACE_TAG_DATA 615 -#define VAR_QUIC_PORT 616 -#define VAR_QUIC_SIZE 617 -#define VAR_PROXY_PROTOCOL_PORT 618 -#define VAR_STATISTICS_INHIBIT_ZERO 619 -#define VAR_HARDEN_UNKNOWN_ADDITIONAL 620 -#define VAR_DISABLE_EDNS_DO 621 -#define VAR_CACHEDB_NO_STORE 622 -#define VAR_LOG_DESTADDR 623 -#define VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED 624 -#define VAR_COOKIE_SECRET_FILE 625 -#define VAR_ITER_SCRUB_NS 626 -#define VAR_ITER_SCRUB_CNAME 627 -#define VAR_MAX_GLOBAL_QUOTA 628 -#define VAR_HARDEN_UNVERIFIED_GLUE 629 -#define VAR_LOG_TIME_ISO 630 +#define VAR_TLS_PROTOCOLS 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_ITER_SCRUB_RRSIG 629 +#define VAR_MAX_TRANSFER_SIZE 630 +#define VAR_MAX_TRANSFER_TIME 631 +#define VAR_MAX_GLOBAL_QUOTA 632 +#define VAR_HARDEN_UNVERIFIED_GLUE 633 +#define VAR_LOG_TIME_ISO 634 +#define VAR_VAL_VALIDATION_ATTEMPTS 635 +#define VAR_VAL_HASH_ATTEMPTS 636 +#define VAR_ITER_SCRUB_PROMISCUOUS 637 +#define VAR_LOG_THREAD_ID 638 #ifndef YYSTYPE_DEFINED #define YYSTYPE_DEFINED typedef union { Index: sbin/unwind/libunbound/util/configparser.y =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/configparser.y,v diff -u -p -r1.21 configparser.y --- sbin/unwind/libunbound/util/configparser.y 29 Sep 2025 14:53:38 -0000 1.21 +++ sbin/unwind/libunbound/util/configparser.y 21 Sep 2026 16:28:28 -0000 @@ -199,6 +199,7 @@ extern struct config_parser_state* cfg_p %token VAR_DISCARD_TIMEOUT VAR_WAIT_LIMIT VAR_WAIT_LIMIT_COOKIE %token VAR_WAIT_LIMIT_NETBLOCK VAR_WAIT_LIMIT_COOKIE_NETBLOCK %token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES VAR_TLS_USE_SNI +%token VAR_TLS_PROTOCOLS %token VAR_IPSET VAR_IPSET_NAME_V4 VAR_IPSET_NAME_V6 %token VAR_TLS_SESSION_TICKET_KEYS VAR_RPZ VAR_TAGS VAR_RPZ_ACTION_OVERRIDE %token VAR_RPZ_CNAME_OVERRIDE VAR_RPZ_LOG VAR_RPZ_LOG_NAME @@ -214,7 +215,11 @@ extern struct config_parser_state* cfg_p %token VAR_HARDEN_UNKNOWN_ADDITIONAL VAR_DISABLE_EDNS_DO VAR_CACHEDB_NO_STORE %token VAR_LOG_DESTADDR VAR_CACHEDB_CHECK_WHEN_SERVE_EXPIRED %token VAR_COOKIE_SECRET_FILE VAR_ITER_SCRUB_NS VAR_ITER_SCRUB_CNAME +%token VAR_ITER_SCRUB_RRSIG +%token VAR_MAX_TRANSFER_SIZE VAR_MAX_TRANSFER_TIME %token VAR_MAX_GLOBAL_QUOTA VAR_HARDEN_UNVERIFIED_GLUE VAR_LOG_TIME_ISO +%token VAR_VAL_VALIDATION_ATTEMPTS VAR_VAL_HASH_ATTEMPTS +%token VAR_ITER_SCRUB_PROMISCUOUS VAR_LOG_THREAD_ID %% toplevelvars: /* empty */ | toplevelvars toplevelvar ; @@ -286,7 +291,7 @@ content_server: server_num_threads | ser server_edns_buffer_size | server_prefetch | server_prefetch_key | server_so_sndbuf | server_harden_below_nxdomain | server_ignore_cd_flag | server_log_queries | server_log_replies | server_tcp_upstream | server_ssl_upstream | - server_log_local_actions | + server_log_local_actions | server_log_thread_id | server_ssl_service_key | server_ssl_service_pem | server_ssl_port | server_https_port | server_http_endpoint | server_http_max_streams | server_http_query_buffer_size | server_http_response_buffer_size | @@ -345,7 +350,7 @@ content_server: server_num_threads | ser server_stream_wait_size | server_tls_ciphers | server_tls_ciphersuites | server_tls_session_ticket_keys | server_answer_cookie | server_cookie_secret | server_ip_ratelimit_cookie | - server_tls_use_sni | server_edns_client_string | + server_tls_use_sni | server_edns_client_string | server_tls_protocols | server_edns_client_string_opcode | server_nsid | server_zonemd_permissive_mode | server_max_reuse_tcp_queries | server_tcp_reuse_timeout | server_tcp_auth_query_timeout | @@ -356,7 +361,9 @@ content_server: server_num_threads | ser server_harden_unknown_additional | server_disable_edns_do | server_log_destaddr | server_cookie_secret_file | server_iter_scrub_ns | server_iter_scrub_cname | server_max_global_quota | - server_harden_unverified_glue | server_log_time_iso + server_val_validation_attempts | + server_val_hash_attempts | server_iter_scrub_rrsig | + server_harden_unverified_glue | server_log_time_iso | server_iter_scrub_promiscuous ; stub_clause: stubstart contents_stub { @@ -455,6 +462,8 @@ authstart: VAR_AUTH_ZONE s->zonemd_check = 0; s->zonemd_reject_absence = 0; s->isrpz = 0; + s->max_transfer_size = 0; + s->max_transfer_time = 0; } else { yyerror("out of memory"); } @@ -464,7 +473,8 @@ contents_auth: contents_auth content_aut | ; content_auth: auth_name | auth_zonefile | auth_master | auth_url | auth_for_downstream | auth_for_upstream | auth_fallback_enabled | - auth_allow_notify | auth_zonemd_check | auth_zonemd_reject_absence + auth_allow_notify | auth_zonemd_check | auth_zonemd_reject_absence | + auth_max_transfer_size | auth_max_transfer_time ; rpz_tag: VAR_TAGS STRING_ARG @@ -552,6 +562,8 @@ rpzstart: VAR_RPZ s->for_upstream = 0; s->fallback_enabled = 0; s->isrpz = 1; + s->max_transfer_size = 0; + s->max_transfer_time = 0; } else { yyerror("out of memory"); } @@ -561,7 +573,8 @@ contents_rpz: contents_rpz content_rpz | ; content_rpz: auth_name | auth_zonefile | rpz_tag | auth_master | auth_url | auth_allow_notify | rpz_action_override | rpz_cname_override | - rpz_log | rpz_log_name | rpz_signal_nxdomain_ra | auth_for_downstream + rpz_log | rpz_log_name | rpz_signal_nxdomain_ra | auth_for_downstream | + auth_max_transfer_size | auth_max_transfer_time ; server_num_threads: VAR_NUM_THREADS STRING_ARG { @@ -653,7 +666,7 @@ server_send_client_subnet: VAR_SEND_CLIE #ifdef CLIENT_SUBNET OUTYY(("P(server_send_client_subnet:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->client_subnet, $2)) - fatal_exit("out of memory adding client-subnet"); + yyerror("out of memory"); #else OUTYY(("P(Compiled without edns subnet option, ignoring)\n")); free($2); @@ -666,7 +679,7 @@ server_client_subnet_zone: VAR_CLIENT_SU OUTYY(("P(server_client_subnet_zone:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->client_subnet_zone, $2)) - fatal_exit("out of memory adding client-subnet-zone"); + yyerror("out of memory"); #else OUTYY(("P(Compiled without edns subnet option, ignoring)\n")); free($2); @@ -1154,6 +1167,15 @@ server_tls_use_sni: VAR_TLS_USE_SNI STRI free($2); } ; +server_tls_protocols: VAR_TLS_PROTOCOLS STRING_ARG + { + OUTYY(("P(server_tls_protocols:%s)\n", $2)); + if(!cfg_tls_protocols_is_valid($2)) + yyerror("tls-protocols: valid values are 'TLSv1.2' and 'TLSv1.3'."); + free(cfg_parser->cfg->tls_protocols); + cfg_parser->cfg->tls_protocols = $2; + } + ; server_https_port: VAR_HTTPS_PORT STRING_ARG { OUTYY(("P(server_https_port:%s)\n", $2)); @@ -1223,14 +1245,17 @@ server_http_notls_downstream: VAR_HTTP_N server_quic_port: VAR_QUIC_PORT STRING_ARG { OUTYY(("P(server_quic_port:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2,"0")!=0) + yyerror("port number expected"); + else { + cfg_parser->cfg->quic_port = atoi($2); #ifndef HAVE_NGTCP2 - log_warn("%s:%d: Unbound is not compiled with " - "ngtcp2. This is required to use DNS " - "over QUIC.", cfg_parser->filename, cfg_parser->line); + if (cfg_parser->cfg->quic_port != 0) + log_warn("%s:%d: Unbound is not compiled with " + "ngtcp2. This is required to use DNS " + "over QUIC.", cfg_parser->filename, cfg_parser->line); #endif - if(atoi($2) == 0) - yyerror("port number expected"); - else cfg_parser->cfg->quic_port = atoi($2); + } free($2); }; server_quic_size: VAR_QUIC_SIZE STRING_ARG @@ -1335,6 +1360,15 @@ server_log_destaddr: VAR_LOG_DESTADDR ST free($2); } ; +server_log_thread_id: VAR_LOG_THREAD_ID STRING_ARG + { + OUTYY(("P(server_log_thread_id:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->log_thread_id = (strcmp($2, "yes")==0); + free($2); + } + ; server_log_local_actions: VAR_LOG_LOCAL_ACTIONS STRING_ARG { OUTYY(("P(server_log_local_actions:%s)\n", $2)); @@ -2004,7 +2038,7 @@ server_access_control: VAR_ACCESS_CONTRO OUTYY(("P(server_access_control:%s %s)\n", $2, $3)); validate_acl_action($3); if(!cfg_str2list_insert(&cfg_parser->cfg->acls, $2, $3)) - fatal_exit("out of memory adding acl"); + yyerror("out of memory"); } ; server_interface_action: VAR_INTERFACE_ACTION STRING_ARG STRING_ARG @@ -2013,7 +2047,7 @@ server_interface_action: VAR_INTERFACE_A validate_acl_action($3); if(!cfg_str2list_insert( &cfg_parser->cfg->interface_actions, $2, $3)) - fatal_exit("out of memory adding acl"); + yyerror("out of memory"); } ; server_module_conf: VAR_MODULE_CONF STRING_ARG @@ -2363,6 +2397,9 @@ server_local_zone: VAR_LOCAL_ZONE STRING && strcmp($3, "typetransparent")!=0 && strcmp($3, "always_transparent")!=0 && strcmp($3, "block_a")!=0 + && strcmp($3, "block_aaaa")!=0 + && strcmp($3, "block_a_wdata")!=0 + && strcmp($3, "block_aaaa_wdata")!=0 && strcmp($3, "always_refuse")!=0 && strcmp($3, "always_nxdomain")!=0 && strcmp($3, "always_nodata")!=0 @@ -2375,7 +2412,9 @@ server_local_zone: VAR_LOCAL_ZONE STRING yyerror("local-zone type: expected static, deny, " "refuse, redirect, transparent, " "typetransparent, inform, inform_deny, " - "inform_redirect, always_transparent, block_a," + "inform_redirect, always_transparent, " + "block_a, block_aaaa, " + "block_a_wdata, block_aaaa_wdata, " "always_refuse, always_nxdomain, " "always_nodata, always_deny, always_null, " "noview, nodefault or ipset"); @@ -2384,7 +2423,7 @@ server_local_zone: VAR_LOCAL_ZONE STRING } else if(strcmp($3, "nodefault")==0) { if(!cfg_strlist_insert(&cfg_parser->cfg-> local_zones_nodefault, $2)) - fatal_exit("out of memory adding local-zone"); + yyerror("out of memory"); free($3); #ifdef USE_IPSET } else if(strcmp($3, "ipset")==0) { @@ -2392,21 +2431,24 @@ server_local_zone: VAR_LOCAL_ZONE STRING /* Make sure to add the trailing dot. * These are str compared to domain names. */ if($2[len-1] != '.') { + char* prev = $2; if(!($2 = realloc($2, len+2))) { - fatal_exit("out of memory adding local-zone"); + yyerror("out of memory"); + free(prev); + } else { + $2[len] = '.'; + $2[len+1] = 0; } - $2[len] = '.'; - $2[len+1] = 0; } if(!cfg_strlist_insert(&cfg_parser->cfg-> local_zones_ipset, $2)) - fatal_exit("out of memory adding local-zone"); + yyerror("out of memory"); free($3); #endif } else { if(!cfg_str2list_insert(&cfg_parser->cfg->local_zones, $2, $3)) - fatal_exit("out of memory adding local-zone"); + yyerror("out of memory"); } } ; @@ -2414,7 +2456,7 @@ server_local_data: VAR_LOCAL_DATA STRING { OUTYY(("P(server_local_data:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->local_data, $2)) - fatal_exit("out of memory adding local-data"); + yyerror("out of memory"); } ; server_local_data_ptr: VAR_LOCAL_DATA_PTR STRING_ARG @@ -2426,7 +2468,7 @@ server_local_data_ptr: VAR_LOCAL_DATA_PT if(ptr) { if(!cfg_strlist_insert(&cfg_parser->cfg-> local_data, ptr)) - fatal_exit("out of memory adding local-data"); + yyerror("out of memory"); } else { yyerror("local-data-ptr could not be reversed"); } @@ -2490,8 +2532,7 @@ server_wait_limit_netblock: VAR_WAIT_LIM } else { if(!cfg_str2list_insert(&cfg_parser->cfg-> wait_limit_netblock, $2, $3)) - fatal_exit("out of memory adding " - "wait-limit-netblock"); + yyerror("out of memory"); } } ; @@ -2505,8 +2546,7 @@ server_wait_limit_cookie_netblock: VAR_W } else { if(!cfg_str2list_insert(&cfg_parser->cfg-> wait_limit_cookie_netblock, $2, $3)) - fatal_exit("out of memory adding " - "wait-limit-cookie-netblock"); + yyerror("out of memory"); } } ; @@ -2538,7 +2578,7 @@ server_dns64_ignore_aaaa: VAR_DNS64_IGNO OUTYY(("P(dns64_ignore_aaaa:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->dns64_ignore_aaaa, $2)) - fatal_exit("out of memory adding dns64-ignore-aaaa"); + yyerror("out of memory"); } ; server_nat64_prefix: VAR_NAT64_PREFIX STRING_ARG @@ -2803,8 +2843,7 @@ server_ratelimit_for_domain: VAR_RATELIM } else { if(!cfg_str2list_insert(&cfg_parser->cfg-> ratelimit_for_domain, $2, $3)) - fatal_exit("out of memory adding " - "ratelimit-for-domain"); + yyerror("out of memory"); } } ; @@ -2818,8 +2857,7 @@ server_ratelimit_below_domain: VAR_RATEL } else { if(!cfg_str2list_insert(&cfg_parser->cfg-> ratelimit_below_domain, $2, $3)) - fatal_exit("out of memory adding " - "ratelimit-below-domain"); + yyerror("out of memory"); } } ; @@ -3053,8 +3091,7 @@ server_edns_client_string: VAR_EDNS_CLIE OUTYY(("P(server_edns_client_string:%s %s)\n", $2, $3)); if(!cfg_str2list_insert( &cfg_parser->cfg->edns_client_strings, $2, $3)) - fatal_exit("out of memory adding " - "edns-client-string"); + yyerror("out of memory"); } ; server_edns_client_string_opcode: VAR_EDNS_CLIENT_STRING_OPCODE STRING_ARG @@ -3316,6 +3353,23 @@ auth_fallback_enabled: VAR_FALLBACK_ENAB free($2); } ; +auth_max_transfer_size: VAR_MAX_TRANSFER_SIZE STRING_ARG + { + OUTYY(("P(max-transfer-size:%s)\n", $2)); + if(!cfg_parse_memsize($2, &cfg_parser->cfg->auths->max_transfer_size)) + yyerror("memory size expected"); + free($2); + } + ; +auth_max_transfer_time: VAR_MAX_TRANSFER_TIME STRING_ARG + { + OUTYY(("P(max-transfer-time:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2, "0") != 0) + yyerror("number expected"); + else cfg_parser->cfg->auths->max_transfer_time = atoi($2); + free($2); + } + ; view_name: VAR_NAME STRING_ARG { OUTYY(("P(name:%s)\n", $2)); @@ -3355,7 +3409,7 @@ view_local_zone: VAR_LOCAL_ZONE STRING_A } else if(strcmp($3, "nodefault")==0) { if(!cfg_strlist_insert(&cfg_parser->cfg->views-> local_zones_nodefault, $2)) - fatal_exit("out of memory adding local-zone"); + yyerror("out of memory"); free($3); #ifdef USE_IPSET } else if(strcmp($3, "ipset")==0) { @@ -3363,22 +3417,25 @@ view_local_zone: VAR_LOCAL_ZONE STRING_A /* Make sure to add the trailing dot. * These are str compared to domain names. */ if($2[len-1] != '.') { + char* prev = $2; if(!($2 = realloc($2, len+2))) { - fatal_exit("out of memory adding local-zone"); + yyerror("out of memory"); + free(prev); + } else { + $2[len] = '.'; + $2[len+1] = 0; } - $2[len] = '.'; - $2[len+1] = 0; } if(!cfg_strlist_insert(&cfg_parser->cfg->views-> local_zones_ipset, $2)) - fatal_exit("out of memory adding local-zone"); + yyerror("out of memory"); free($3); #endif } else { if(!cfg_str2list_insert( &cfg_parser->cfg->views->local_zones, $2, $3)) - fatal_exit("out of memory adding local-zone"); + yyerror("out of memory"); } } ; @@ -3388,8 +3445,7 @@ view_response_ip: VAR_RESPONSE_IP STRING validate_respip_action($3); if(!cfg_str2list_insert( &cfg_parser->cfg->views->respip_actions, $2, $3)) - fatal_exit("out of memory adding per-view " - "response-ip action"); + yyerror("out of memory"); } ; view_response_ip_data: VAR_RESPONSE_IP_DATA STRING_ARG STRING_ARG @@ -3397,14 +3453,14 @@ view_response_ip_data: VAR_RESPONSE_IP_D OUTYY(("P(view_response_ip_data:%s)\n", $2)); if(!cfg_str2list_insert( &cfg_parser->cfg->views->respip_data, $2, $3)) - fatal_exit("out of memory adding response-ip-data"); + yyerror("out of memory"); } ; view_local_data: VAR_LOCAL_DATA STRING_ARG { OUTYY(("P(view_local_data:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->views->local_data, $2)) { - fatal_exit("out of memory adding local-data"); + yyerror("out of memory"); } } ; @@ -3417,7 +3473,7 @@ view_local_data_ptr: VAR_LOCAL_DATA_PTR if(ptr) { if(!cfg_strlist_insert(&cfg_parser->cfg->views-> local_data, ptr)) - fatal_exit("out of memory adding local-data"); + yyerror("out of memory"); } else { yyerror("local-data-ptr could not be reversed"); } @@ -3757,7 +3813,7 @@ server_response_ip: VAR_RESPONSE_IP STRI validate_respip_action($3); if(!cfg_str2list_insert(&cfg_parser->cfg->respip_actions, $2, $3)) - fatal_exit("out of memory adding response-ip"); + yyerror("out of memory"); } ; server_response_ip_data: VAR_RESPONSE_IP_DATA STRING_ARG STRING_ARG @@ -3765,7 +3821,7 @@ server_response_ip_data: VAR_RESPONSE_IP OUTYY(("P(server_response_ip_data:%s)\n", $2)); if(!cfg_str2list_insert(&cfg_parser->cfg->respip_data, $2, $3)) - fatal_exit("out of memory adding response-ip-data"); + yyerror("out of memory"); } ; dnscstart: VAR_DNSCRYPT @@ -3813,26 +3869,30 @@ dnsc_dnscrypt_provider: VAR_DNSCRYPT_PRO dnsc_dnscrypt_provider_cert: VAR_DNSCRYPT_PROVIDER_CERT STRING_ARG { OUTYY(("P(dnsc_dnscrypt_provider_cert:%s)\n", $2)); - if(cfg_strlist_find(cfg_parser->cfg->dnscrypt_provider_cert, $2)) + if(cfg_strlist_find(cfg_parser->cfg->dnscrypt_provider_cert, $2)) { log_warn("dnscrypt-provider-cert %s is a duplicate", $2); - if(!cfg_strlist_insert(&cfg_parser->cfg->dnscrypt_provider_cert, $2)) - fatal_exit("out of memory adding dnscrypt-provider-cert"); + free($2); + } else if(!cfg_strlist_insert(&cfg_parser->cfg->dnscrypt_provider_cert, $2)) { + yyerror("out of memory"); + } } ; dnsc_dnscrypt_provider_cert_rotated: VAR_DNSCRYPT_PROVIDER_CERT_ROTATED STRING_ARG { OUTYY(("P(dnsc_dnscrypt_provider_cert_rotated:%s)\n", $2)); if(!cfg_strlist_insert(&cfg_parser->cfg->dnscrypt_provider_cert_rotated, $2)) - fatal_exit("out of memory adding dnscrypt-provider-cert-rotated"); + yyerror("out of memory"); } ; dnsc_dnscrypt_secret_key: VAR_DNSCRYPT_SECRET_KEY STRING_ARG { OUTYY(("P(dnsc_dnscrypt_secret_key:%s)\n", $2)); - if(cfg_strlist_find(cfg_parser->cfg->dnscrypt_secret_key, $2)) + if(cfg_strlist_find(cfg_parser->cfg->dnscrypt_secret_key, $2)) { log_warn("dnscrypt-secret-key: %s is a duplicate", $2); - if(!cfg_strlist_insert(&cfg_parser->cfg->dnscrypt_secret_key, $2)) - fatal_exit("out of memory adding dnscrypt-secret-key"); + free($2); + } else if(!cfg_strlist_insert(&cfg_parser->cfg->dnscrypt_secret_key, $2)) { + yyerror("out of memory"); + } } ; dnsc_dnscrypt_shared_secret_cache_size: VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE STRING_ARG @@ -4177,7 +4237,7 @@ server_tcp_connection_limit: VAR_TCP_CON yyerror("positive number expected"); else { if(!cfg_str2list_insert(&cfg_parser->cfg->tcp_connection_limits, $2, $3)) - fatal_exit("out of memory adding tcp connection limit"); + yyerror("out of memory"); } } ; @@ -4216,8 +4276,8 @@ server_cookie_secret_file: VAR_COOKIE_SE server_iter_scrub_ns: VAR_ITER_SCRUB_NS STRING_ARG { OUTYY(("P(server_iter_scrub_ns:%s)\n", $2)); - if(atoi($2) == 0 && strcmp($2, "0") != 0) - yyerror("number expected"); + if(atoi($2) < 1) + yyerror("number >= 1 expected"); else cfg_parser->cfg->iter_scrub_ns = atoi($2); free($2); } @@ -4231,12 +4291,49 @@ server_iter_scrub_cname: VAR_ITER_SCRUB_ free($2); } ; +server_iter_scrub_rrsig: VAR_ITER_SCRUB_RRSIG STRING_ARG + { + OUTYY(("P(server_iter_scrub_rrsig:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2, "0") != 0) + yyerror("number expected"); + else cfg_parser->cfg->iter_scrub_rrsig = atoi($2); + free($2); + } + ; server_max_global_quota: VAR_MAX_GLOBAL_QUOTA STRING_ARG { OUTYY(("P(server_max_global_quota:%s)\n", $2)); if(atoi($2) == 0 && strcmp($2, "0") != 0) yyerror("number expected"); else cfg_parser->cfg->max_global_quota = atoi($2); + free($2); + } + ; +server_iter_scrub_promiscuous: VAR_ITER_SCRUB_PROMISCUOUS STRING_ARG + { + OUTYY(("P(server_iter_scrub_promiscuous:%s)\n", $2)); + if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0) + yyerror("expected yes or no."); + else cfg_parser->cfg->iter_scrub_promiscuous = + (strcmp($2, "yes")==0); + free($2); + } + ; +server_val_validation_attempts: VAR_VAL_VALIDATION_ATTEMPTS STRING_ARG + { + OUTYY(("P(server_val_validation_attempts:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2, "0") != 0) + yyerror("number expected"); + else cfg_parser->cfg->val_validation_attempts = atoi($2); + free($2); + } + ; +server_val_hash_attempts: VAR_VAL_HASH_ATTEMPTS STRING_ARG + { + OUTYY(("P(server_val_hash_attempts:%s)\n", $2)); + if(atoi($2) == 0 && strcmp($2, "0") != 0) + yyerror("number expected"); + else cfg_parser->cfg->val_hash_attempts = atoi($2); free($2); } ; Index: sbin/unwind/libunbound/util/fptr_wlist.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/fptr_wlist.c,v diff -u -p -r1.16 fptr_wlist.c --- sbin/unwind/libunbound/util/fptr_wlist.c 14 Sep 2025 15:16:53 -0000 1.16 +++ sbin/unwind/libunbound/util/fptr_wlist.c 21 Sep 2026 16:28:28 -0000 @@ -141,6 +141,8 @@ fptr_whitelist_comm_timer(void (*fptr)(v #ifdef UB_ON_WINDOWS else if(fptr == &wsvc_cron_cb) return 1; #endif + else if(fptr == &tcp_read_again_cb) return 1; + else if(fptr == &tcp_more_read_again_cb) return 1; else if(fptr == &auth_xfer_timer) return 1; else if(fptr == &auth_xfer_probe_timer_callback) return 1; else if(fptr == &auth_xfer_transfer_timer_callback) return 1; @@ -362,7 +364,7 @@ fptr_whitelist_modenv_send_query(struct int nocaps, int check_ratelimit, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name, struct module_qstate* q, - int* was_ratelimited)) + int* was_ratelimited, int* ratelimit_incremented)) { if(fptr == &worker_send_query) return 1; else if(fptr == &libworker_send_query) return 1; @@ -380,7 +382,8 @@ fptr_whitelist_modenv_detach_subs(void ( int fptr_whitelist_modenv_attach_sub(int (*fptr)( struct module_qstate* qstate, struct query_info* qinfo, - uint16_t qflags, int prime, int valrec, struct module_qstate** newq)) + struct respip_client_info* cinfo, uint16_t qflags, int prime, + int valrec, struct module_qstate** newq)) { if(fptr == &mesh_attach_sub) return 1; return 0; @@ -389,8 +392,8 @@ fptr_whitelist_modenv_attach_sub(int (*f int fptr_whitelist_modenv_add_sub(int (*fptr)( struct module_qstate* qstate, struct query_info* qinfo, - uint16_t qflags, int prime, int valrec, struct module_qstate** newq, - struct mesh_state** sub)) + struct respip_client_info* cinfo, uint16_t qflags, int prime, + int valrec, struct module_qstate** newq, struct mesh_state** sub)) { if(fptr == &mesh_add_sub) return 1; return 0; @@ -412,7 +415,7 @@ fptr_whitelist_modenv_detect_cycle(int ( return 0; } -int +int fptr_whitelist_mod_init(int (*fptr)(struct module_env* env, int id)) { if(fptr == &iter_init) return 1; @@ -440,7 +443,7 @@ fptr_whitelist_mod_init(int (*fptr)(stru return 0; } -int +int fptr_whitelist_mod_deinit(void (*fptr)(struct module_env* env, int id)) { if(fptr == &iter_deinit) return 1; @@ -609,6 +612,7 @@ int fptr_whitelist_alloc_cleanup(void (*fptr)(void*)) { if(fptr == &worker_alloc_cleanup) return 1; + else if(fptr == &libworker_alloc_cleanup) return 1; return 0; } Index: sbin/unwind/libunbound/util/fptr_wlist.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/fptr_wlist.h,v diff -u -p -r1.4 fptr_wlist.h --- sbin/unwind/libunbound/util/fptr_wlist.h 5 Sep 2024 08:22:47 -0000 1.4 +++ sbin/unwind/libunbound/util/fptr_wlist.h 21 Sep 2026 16:28:28 -0000 @@ -214,7 +214,7 @@ int fptr_whitelist_modenv_send_query(str int nocaps, int check_ratelimit, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream, char* tls_auth_name, struct module_qstate* q, - int* was_ratelimited)); + int* was_ratelimited, int* ratelimit_incremented)); /** * Check function pointer whitelist for module_env detach_subs callback values. @@ -233,7 +233,8 @@ int fptr_whitelist_modenv_detach_subs(vo */ int fptr_whitelist_modenv_attach_sub(int (*fptr)( struct module_qstate* qstate, struct query_info* qinfo, - uint16_t qflags, int prime, int valrec, struct module_qstate** newq)); + struct respip_client_info* cinfo, uint16_t qflags, int prime, + int valrec, struct module_qstate** newq)); /** * Check function pointer whitelist for module_env add_sub callback values. @@ -242,8 +243,9 @@ int fptr_whitelist_modenv_attach_sub(int * @return false if not in whitelist. */ int fptr_whitelist_modenv_add_sub(int (*fptr)(struct module_qstate* qstate, - struct query_info* qinfo, uint16_t qflags, int prime, int valrec, - struct module_qstate** newq, struct mesh_state** sub)); + struct query_info* qinfo, struct respip_client_info* cinfo, + uint16_t qflags, int prime, int valrec, struct module_qstate** newq, + struct mesh_state** sub)); /** * Check function pointer whitelist for module_env kill_sub callback values. * Index: sbin/unwind/libunbound/util/iana_ports.inc =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/iana_ports.inc,v diff -u -p -r1.16 iana_ports.inc --- sbin/unwind/libunbound/util/iana_ports.inc 29 Sep 2025 14:53:38 -0000 1.16 +++ sbin/unwind/libunbound/util/iana_ports.inc 21 Sep 2026 16:28:28 -0000 @@ -649,9 +649,6 @@ 828, 829, 830, -831, -832, -833, 847, 848, 853, @@ -3869,6 +3866,7 @@ 4456, 4457, 4458, +4480, 4484, 4486, 4488, @@ -3981,6 +3979,7 @@ 4791, 4792, 4793, +4794, 4800, 4801, 4802, @@ -4173,6 +4172,7 @@ 5313, 5314, 5315, +5319, 5343, 5344, 5349, @@ -4507,6 +4507,7 @@ 6581, 6582, 6583, +6610, 6619, 6620, 6621, @@ -4609,6 +4610,7 @@ 7101, 7107, 7121, +7123, 7128, 7129, 7161, @@ -4950,6 +4952,7 @@ 9162, 9163, 9164, +9183, 9191, 9200, 9201, @@ -5343,6 +5346,7 @@ 24465, 24554, 24577, +24601, 24676, 24677, 24678, @@ -5392,6 +5396,7 @@ 30004, 30260, 30832, +30939, 30999, 31016, 31029, @@ -5433,6 +5438,8 @@ 34962, 34963, 34964, +34965, +34966, 34980, 35001, 35004, Index: sbin/unwind/libunbound/util/locks.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/locks.h,v diff -u -p -r1.2 locks.h --- sbin/unwind/libunbound/util/locks.h 23 Feb 2025 07:53:40 -0000 1.2 +++ sbin/unwind/libunbound/util/locks.h 21 Sep 2026 16:28:28 -0000 @@ -178,6 +178,30 @@ typedef pthread_key_t ub_thread_key_type #define ub_thread_key_set(key, v) LOCKRET(pthread_setspecific(key, v)) #define ub_thread_key_get(key) pthread_getspecific(key) +#ifdef HAVE_PTHREAD_NP_H +#include +#endif +#if defined(HAVE_PTHREAD_SET_NAME_NP) + #define ub_thread_setname(thread, name) do { \ + (void)pthread_set_name_np(thread, name);\ + } while(0) +#elif defined(HAVE_PTHREAD_SETNAME_NP1) + #define ub_thread_setname(thread, name) do { \ + (void)pthread_setname_np(name); \ + } while(0) +#elif defined(HAVE_PTHREAD_SETNAME_NP3) + #define ub_thread_setname(thread, name) do { \ + (void)pthread_setname_np(thread, name, NULL); \ + } while(0) +#elif defined(HAVE_PTHREAD_SETNAME_NP) + #define ub_thread_setname(thread, name) do { \ + (void)pthread_setname_np(thread, name); \ + } while(0) +#else + #define ub_thread_setname(thread, name) /* nop */ +#endif /* HAVE_PTHREAD_SET_NAME_NP */ + + #else /* we do not HAVE_PTHREAD */ #ifdef HAVE_SOLARIS_THREADS @@ -215,6 +239,7 @@ typedef thread_key_t ub_thread_key_type; #define ub_thread_key_create(key, f) LOCKRET(thr_keycreate(key, f)) #define ub_thread_key_set(key, v) LOCKRET(thr_setspecific(key, v)) void* ub_thread_key_get(ub_thread_key_type key); +#define ub_thread_setname(thread, name) /* nop */ #else /* we do not HAVE_SOLARIS_THREADS and no PTHREADS */ @@ -253,6 +278,7 @@ typedef DWORD ub_thread_key_type; void ub_thread_key_create(ub_thread_key_type* key, void* f); void ub_thread_key_set(ub_thread_key_type key, void* v); void* ub_thread_key_get(ub_thread_key_type key); +#define ub_thread_setname(thread, name) /* nop */ #else /* we do not HAVE_SOLARIS_THREADS, PTHREADS or WINDOWS_THREADS */ @@ -294,6 +320,7 @@ typedef void* ub_thread_key_type; #define ub_thread_key_create(key, f) (*(key)) = NULL #define ub_thread_key_set(key, v) (key) = (v) #define ub_thread_key_get(key) (key) +#define ub_thread_setname(thread, name) /* nop */ #endif /* HAVE_WINDOWS_THREADS */ #endif /* HAVE_SOLARIS_THREADS */ Index: sbin/unwind/libunbound/util/log.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/log.c,v diff -u -p -r1.10 log.c --- sbin/unwind/libunbound/util/log.c 14 Sep 2025 15:16:53 -0000 1.10 +++ sbin/unwind/libunbound/util/log.c 21 Sep 2026 16:28:28 -0000 @@ -174,10 +174,10 @@ void log_thread_set(int* num) int log_thread_get(void) { - unsigned int* tid; + int* tid; if(!key_created) return 0; - tid = (unsigned int*)ub_thread_key_get(logkey); - return (int)(tid?*tid:0); + tid = ub_thread_key_get(logkey); + return (tid?*tid:0); } void log_ident_set(const char* id) @@ -229,7 +229,7 @@ log_vmsg(int pri, const char* type, const char *format, va_list args) { char message[MAXSYSLOGMSGLEN]; - unsigned int* tid = (unsigned int*)ub_thread_key_get(logkey); + int tid = log_thread_get(); time_t now; #if defined(HAVE_STRFTIME) && defined(HAVE_LOCALTIME_R) char tmbuf[32]; @@ -241,8 +241,8 @@ log_vmsg(int pri, const char* type, vsnprintf(message, sizeof(message), format, args); #ifdef HAVE_SYSLOG_H if(logging_to_syslog) { - syslog(pri, "[%d:%x] %s: %s", - (int)getpid(), tid?*tid:0, type, message); + syslog(pri, "[%d:%d] %s: %s", + (int)getpid(), tid, type, message); return; } #elif defined(UB_ON_WINDOWS) @@ -263,8 +263,8 @@ log_vmsg(int pri, const char* type, tp=MSG_GENERIC_SUCCESS; wt=EVENTLOG_SUCCESS; } - snprintf(m, sizeof(m), "[%s:%x] %s: %s", - ident, tid?*tid:0, type, message); + snprintf(m, sizeof(m), "[%s:%d] %s: %s", + ident, tid, type, message); s = RegisterEventSource(NULL, SERVICE_NAME); if(!s) return; ReportEvent(s, wt, 0, tp, NULL, 1, 0, &str, NULL); @@ -294,9 +294,9 @@ log_vmsg(int pri, const char* type, tzbuf[3] = ':'; tzbuf[6] = 0; } - fprintf(logfile, "%s.%3.3d%s %s[%d:%x] %s: %s\n", + fprintf(logfile, "%s.%3.3d%s %s[%d:%d] %s: %s\n", tmbuf, (int)tv.tv_usec/1000, tzbuf, - ident, (int)getpid(), tid?*tid:0, type, message); + ident, (int)getpid(), tid, type, message); #ifdef UB_ON_WINDOWS /* line buffering does not work on windows */ fflush(logfile); @@ -310,19 +310,19 @@ log_vmsg(int pri, const char* type, if(log_time_asc && localtime_r(&now, &tm) && strftime(tmbuf, sizeof(tmbuf), "%b %d %H:%M:%S", &tm)%(sizeof(tmbuf)) != 0) { /* %sizeof buf!=0 because old strftime returned max on error */ - fprintf(logfile, "%s %s[%d:%x] %s: %s\n", tmbuf, - ident, (int)getpid(), tid?*tid:0, type, message); + fprintf(logfile, "%s %s[%d:%d] %s: %s\n", tmbuf, + ident, (int)getpid(), tid, type, message); } else #elif defined(UB_ON_WINDOWS) if(log_time_asc && GetTimeFormat(LOCALE_USER_DEFAULT, 0, NULL, NULL, tmbuf, sizeof(tmbuf)) && GetDateFormat(LOCALE_USER_DEFAULT, 0, NULL, NULL, dtbuf, sizeof(dtbuf))) { - fprintf(logfile, "%s %s %s[%d:%x] %s: %s\n", dtbuf, tmbuf, - ident, (int)getpid(), tid?*tid:0, type, message); + fprintf(logfile, "%s %s %s[%d:%d] %s: %s\n", dtbuf, tmbuf, + ident, (int)getpid(), tid, type, message); } else #endif - fprintf(logfile, "[" ARG_LL "d] %s[%d:%x] %s: %s\n", (long long)now, - ident, (int)getpid(), tid?*tid:0, type, message); + fprintf(logfile, "[" ARG_LL "d] %s[%d:%d] %s: %s\n", (long long)now, + ident, (int)getpid(), tid, type, message); #ifdef UB_ON_WINDOWS /* line buffering does not work on windows */ fflush(logfile); Index: sbin/unwind/libunbound/util/module.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/module.h,v diff -u -p -r1.14 module.h --- sbin/unwind/libunbound/util/module.h 14 Sep 2025 15:16:53 -0000 1.14 +++ sbin/unwind/libunbound/util/module.h 21 Sep 2026 16:28:28 -0000 @@ -375,6 +375,8 @@ struct module_env { * @param q: which query state to reactivate upon return. * @param was_ratelimited: it will signal back if the query failed to pass the * ratelimit check. + * @param ratelimit_incremented: set to true if the ratelimit counter + * was increased. * @return: false on failure (memory or socket related). no query was * sent. Or returns an outbound entry with qsent and qstate set. * This outbound_entry will be used on later module invocations @@ -385,7 +387,8 @@ struct module_env { int check_ratelimit, struct sockaddr_storage* addr, socklen_t addrlen, uint8_t* zone, size_t zonelen, int tcp_upstream, int ssl_upstream, - char* tls_auth_name, struct module_qstate* q, int* was_ratelimited); + char* tls_auth_name, struct module_qstate* q, int* was_ratelimited, + int* ratelimit_incremented); /** * Detach-subqueries. @@ -411,6 +414,8 @@ struct module_env { * @param qstate: the state to find mesh state, and that wants to * receive the results from the new subquery. * @param qinfo: what to query for (copied). + * @param cinfo: if non-NULL client specific info that may affect + * IP-based actions that apply to the query result. * @param qflags: what flags to use (RD, CD flag or not). * @param prime: if it is a (stub) priming query. * @param valrec: validation lookup recursion, does not need validation @@ -419,8 +424,9 @@ struct module_env { * @return: false on error, true if success (and init may be needed). */ int (*attach_sub)(struct module_qstate* qstate, - struct query_info* qinfo, uint16_t qflags, int prime, - int valrec, struct module_qstate** newq); + struct query_info* qinfo, struct respip_client_info* cinfo, + uint16_t qflags, int prime, int valrec, + struct module_qstate** newq); /** * Add detached query. @@ -440,6 +446,8 @@ struct module_env { * @param qstate: the state to find mesh state, and that wants to receive * the results from the new subquery. * @param qinfo: what to query for (copied). + * @param cinfo: if non-NULL client specific info that may affect + * IP-based actions that apply to the query result. * @param qflags: what flags to use (RD / CD flag or not). * @param prime: if it is a (stub) priming query. * @param valrec: if it is a validation recursion query (lookup of key, DS). @@ -449,9 +457,9 @@ struct module_env { * @return: false on error, true if success (and init may be needed). */ int (*add_sub)(struct module_qstate* qstate, - struct query_info* qinfo, uint16_t qflags, int prime, - int valrec, struct module_qstate** newq, - struct mesh_state** sub); + struct query_info* qinfo, struct respip_client_info* cinfo, + uint16_t qflags, int prime, int valrec, + struct module_qstate** newq, struct mesh_state** sub); /** * Kill newly attached sub. If attach_sub returns newq for @@ -693,6 +701,16 @@ struct module_qstate { time_t qstarttime; /** whether a message from cachedb will be used for the reply */ int is_cachedb_answer; + /** whether the reply is subnet specific */ + int is_subnet_answer; + /** if the response as error is from error_response_cache, and is + * suitable for caching (briefly) the error response. Set by the + * iterator when no_cache_store is enabled, and there is an error. */ + int error_response_cache; + /** if the iterator sees that the forward/stub has no_cache set. + * to signal to calling modules that their setting of no_cache for + * other reasons, has to take into account the fwd/stub no_cache. */ + int fwd_stub_no_cache; /** * Attributes of clients that share the qstate that may affect IP-based @@ -712,6 +730,12 @@ struct module_qstate { /** whether the reply should be dropped */ int is_drop; + /** the global quota that was reached, by one of the modules. + * So that continued counting can go on from that point. */ + int global_quota_reached; + /** the global quota that a query started with, it is a subquery, + * so that calling mesh states can see the increase. */ + int global_quota_started; }; /** @@ -721,7 +745,7 @@ struct module_func_block { /** text string name of module */ const char* name; - /** + /** * Set up the module for start. This is called only once at startup. * Privileged operations like opening device files may be done here. * The function ptr can be NULL, if it is not used. Index: sbin/unwind/libunbound/util/net_help.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/net_help.c,v diff -u -p -r1.23 net_help.c --- sbin/unwind/libunbound/util/net_help.c 29 Sep 2025 14:53:38 -0000 1.23 +++ sbin/unwind/libunbound/util/net_help.c 21 Sep 2026 16:28:28 -0000 @@ -242,7 +242,7 @@ int extstrtoaddr(const char* str, struct sockaddr_storage* addr, socklen_t* addrlen, int port) { - char* s; + const char* s; if((s=strchr(str, '@'))) { char buf[MAX_ADDR_STRLEN]; if(s-str >= MAX_ADDR_STRLEN) { @@ -268,7 +268,7 @@ ipstrtoaddr(const char* ip, int port, st p = (uint16_t) port; if(str_is_ip6(ip)) { char buf[MAX_ADDR_STRLEN]; - char* s; + const char* s; struct sockaddr_in6* sa = (struct sockaddr_in6*)addr; *addrlen = (socklen_t)sizeof(struct sockaddr_in6); memset(sa, 0, *addrlen); @@ -304,8 +304,9 @@ ipstrtoaddr(const char* ip, int port, st int netblockstrtoaddr(const char* str, int port, struct sockaddr_storage* addr, socklen_t* addrlen, int* net) { + const char* s; char buf[64]; - char* s; + char* b = NULL; *net = (str_is_ip6(str)?128:32); if((s=strchr(str, '/'))) { if(atoi(s+1) > *net) { @@ -323,15 +324,15 @@ int netblockstrtoaddr(const char* str, i return 0; } strlcpy(buf, str, sizeof(buf)); - s = strchr(buf, '/'); - if(s) *s = 0; - s = buf; + b = strchr(buf, '/'); + if(b) *b = 0; + b = buf; } - if(!ipstrtoaddr(s?s:str, port, addr, addrlen)) { + if(!ipstrtoaddr(b?b:str, port, addr, addrlen)) { log_err("cannot parse ip address: '%s'", str); return 0; } - if(s) { + if(b) { addr_mask(addr, *addrlen, *net); } return 1; @@ -783,7 +784,7 @@ sockaddr_cmp_scopeid(struct sockaddr_sto } int -addr_is_ip6(struct sockaddr_storage* addr, socklen_t len) +addr_is_ip6(const struct sockaddr_storage* addr, socklen_t len) { if(len == (socklen_t)sizeof(struct sockaddr_in6) && ((struct sockaddr_in6*)addr)->sin6_family == AF_INET6) @@ -1226,10 +1227,13 @@ setup_ticket_keys_cb(void* sslctx) #endif /* HAVE_SSL */ int -listen_sslctx_setup(void* ctxt) +listen_sslctx_setup(void* ctxt, const char* tls_protocols) { #ifdef HAVE_SSL + int allow12, allow13; SSL_CTX* ctx = (SSL_CTX*)ctxt; + cfg_tls_protocols_allowed(tls_protocols, &allow12, &allow13); + /* no SSLv2, SSLv3 because has defects */ #if SSL_OP_NO_SSLv2 != 0 if((SSL_CTX_set_options(ctx, SSL_OP_NO_SSLv2) & SSL_OP_NO_SSLv2) @@ -1259,12 +1263,24 @@ listen_sslctx_setup(void* ctxt) return 0; } #endif -#if defined(SSL_OP_NO_TLSv1_2) && defined(SSL_OP_NO_TLSv1_3) - /* if we have tls 1.3 disable 1.2 */ - if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2) & SSL_OP_NO_TLSv1_2) - != SSL_OP_NO_TLSv1_2){ - log_crypto_err("could not set SSL_OP_NO_TLSv1_2"); - return 0; +#if defined(SSL_OP_NO_TLSv1_2) + if(!allow12) { + /* we are not allowed to use TLS1.2 */ + if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_2) & SSL_OP_NO_TLSv1_2) + != SSL_OP_NO_TLSv1_2){ + log_crypto_err("could not set SSL_OP_NO_TLSv1_2"); + return 0; + } + } +#endif +#if defined(SSL_OP_NO_TLSv1_3) + if(!allow13) { + /* we are not allowed to use TLS1.3 */ + if((SSL_CTX_set_options(ctx, SSL_OP_NO_TLSv1_3) & SSL_OP_NO_TLSv1_3) + != SSL_OP_NO_TLSv1_3){ + log_crypto_err("could not set SSL_OP_NO_TLSv1_3"); + return 0; + } } #endif #if defined(SSL_OP_NO_RENEGOTIATION) @@ -1305,7 +1321,7 @@ listen_sslctx_setup(void* ctxt) SSL_CTX_set_security_level(ctx, 0); #endif #else - (void)ctxt; + (void)ctxt; (void)tls_protocols; #endif /* HAVE_SSL */ return 1; } @@ -1341,7 +1357,7 @@ listen_sslctx_setup_2(void* ctxt) 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) + int is_dot, int is_doh, const char* tls_protocols) { #ifdef HAVE_SSL SSL_CTX* ctx = SSL_CTX_new(SSLv23_server_method()); @@ -1359,7 +1375,7 @@ void* listen_sslctx_create(const char* k SSL_CTX_free(ctx); return NULL; } - if(!listen_sslctx_setup(ctx)) { + if(!listen_sslctx_setup(ctx, tls_protocols)) { SSL_CTX_free(ctx); return NULL; } @@ -1430,12 +1446,15 @@ void* listen_sslctx_create(const char* k SSL_CTX_set_alpn_select_cb(ctx, doh_alpn_select_cb, NULL); #endif } +#else /* HAVE_SSL_CTX_SET_ALPN_SELECT_CB */ + (void)is_dot; (void)is_doh; #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; + (void)tls_protocols; return NULL; #endif /* HAVE_SSL */ } @@ -1688,6 +1707,10 @@ int check_auth_name_for_ssl(char* auth_n /** set the authname on an SSL structure, SSL* ssl */ int set_auth_name_on_ssl(void* ssl, char* auth_name, int use_sni) { +#ifdef HAVE_SSL_SET1_DNSNAME + struct sockaddr_storage tmpaddr; + socklen_t tmpaddrlen = (socklen_t)sizeof(tmpaddr); +#endif if(!auth_name) return 1; #ifdef HAVE_SSL if(use_sni) { @@ -1697,7 +1720,20 @@ int set_auth_name_on_ssl(void* ssl, char (void)ssl; (void)use_sni; #endif -#ifdef HAVE_SSL_SET1_HOST +#ifdef HAVE_SSL_SET1_DNSNAME + SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL); + if(ipstrtoaddr(auth_name, UNBOUND_DNS_PORT, &tmpaddr, &tmpaddrlen)) { + if(!SSL_set1_ipaddr(ssl, auth_name)) { + log_err("SSL_set1_ipaddr failed"); + return 0; + } + } else { + if(!SSL_set1_dnsname(ssl, auth_name)) { + log_err("SSL_set1_dnsname failed"); + return 0; + } + } +#elif defined(HAVE_SSL_SET1_HOST) SSL_set_verify(ssl, SSL_VERIFY_PEER, NULL); /* setting the hostname makes openssl verify the * host name in the x509 certificate in the @@ -1797,7 +1833,7 @@ void ub_openssl_lock_delete(void) #endif /* OPENSSL_THREADS */ } -int listen_sslctx_setup_ticket_keys(struct config_strlist* tls_session_ticket_keys) { +int listen_sslctx_setup_ticket_keys(struct config_strlist* tls_session_ticket_keys, char* chroot) { #ifdef HAVE_SSL size_t s = 1; struct config_strlist* p; @@ -1815,14 +1851,18 @@ int listen_sslctx_setup_ticket_keys(stru size_t n; unsigned char *data; FILE *f; + char* fstr; data = (unsigned char *)malloc(80); if(!data) return 0; - f = fopen(p->str, "rb"); + fstr = p->str; + if(chroot && strncmp(fstr, chroot, strlen(chroot)) == 0) + fstr += strlen(chroot); + f = fopen(fstr, "rb"); if(!f) { - log_err("could not read tls-session-ticket-key %s: %s", p->str, strerror(errno)); + log_err("could not read tls-session-ticket-key %s: %s", fstr, strerror(errno)); free(data); return 0; } @@ -1830,11 +1870,11 @@ int listen_sslctx_setup_ticket_keys(stru fclose(f); if(n != 80) { - log_err("tls-session-ticket-key %s is %d bytes, must be 80 bytes", p->str, (int)n); + log_err("tls-session-ticket-key %s is %d bytes, must be 80 bytes", fstr, (int)n); free(data); return 0; } - verbose(VERB_OPS, "read tls-session-ticket-key: %s", p->str); + verbose(VERB_OPS, "read tls-session-ticket-key: %s", fstr); keys->key_name = data; keys->aes_key = data + 16; @@ -1845,7 +1885,7 @@ int listen_sslctx_setup_ticket_keys(stru keys->key_name = NULL; return 1; #else - (void)tls_session_ticket_keys; + (void)tls_session_ticket_keys; (void)chroot; return 0; #endif } Index: sbin/unwind/libunbound/util/net_help.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/net_help.h,v diff -u -p -r1.13 net_help.h --- sbin/unwind/libunbound/util/net_help.h 14 Sep 2025 15:16:53 -0000 1.13 +++ sbin/unwind/libunbound/util/net_help.h 21 Sep 2026 16:28:28 -0000 @@ -307,7 +307,7 @@ int sockaddr_cmp_scopeid(struct sockaddr * @param len: the length of addr. * @return: true if sockaddr is ip6. */ -int addr_is_ip6(struct sockaddr_storage* addr, socklen_t len); +int addr_is_ip6(const struct sockaddr_storage* addr, socklen_t len); /** * Make sure the sockaddr ends in zeroes. For tree insertion and subsequent @@ -478,9 +478,10 @@ void log_cert(unsigned level, const char /** * Set SSL_OP_NOxxx options on SSL context to disable bad crypto * @param ctxt: SSL_CTX* + * @param tls_protocols: configure string with allowed TLS protocols to use. * @return false on failure. */ -int listen_sslctx_setup(void* ctxt); +int listen_sslctx_setup(void* ctxt, const char* tls_protocols); /** * Further setup of listening SSL context, after keys loaded. @@ -499,12 +500,13 @@ void listen_sslctx_setup_2(void* ctxt); * 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. + * @param tls_protocols: configure string with allowed TLS protocols to use. * return SSL_CTX* or NULL on failure (logged). */ 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); + int is_dot, int is_doh, const char* tls_protocols); /** * create SSL connect context @@ -563,9 +565,11 @@ void ub_openssl_lock_delete(void); /** * setup TLS session ticket * @param tls_session_ticket_keys: TLS ticket secret filenames + * @param chroot: if not NULL, the chroot that is in use. * @return false on failure (alloc failure). */ -int listen_sslctx_setup_ticket_keys(struct config_strlist* tls_session_ticket_keys); +int listen_sslctx_setup_ticket_keys( + struct config_strlist* tls_session_ticket_keys, char* chroot); /** Free memory used for TLS session ticket keys */ void listen_sslctx_delete_ticket_keys(void); Index: sbin/unwind/libunbound/util/netevent.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/netevent.c,v diff -u -p -r1.26 netevent.c --- sbin/unwind/libunbound/util/netevent.c 29 Sep 2025 14:53:38 -0000 1.26 +++ sbin/unwind/libunbound/util/netevent.c 21 Sep 2026 16:28:29 -0000 @@ -122,6 +122,10 @@ #define NUM_UDP_PER_SELECT 1 #endif +/** The number of TCP queries over a TCP connection, per read indication + * from select. */ +#define NUM_TCP_PER_SELECT 100 + /** timeout in millisec to wait for write to unblock, packets dropped after.*/ #define SEND_BLOCKED_WAIT_TIMEOUT 200 /** max number of times to wait for write to unblock, packets dropped after.*/ @@ -951,6 +955,10 @@ static int consume_pp2_header(struct sld { struct sockaddr_in* addr = (struct sockaddr_in*)&rep->client_addr; + if(ntohs(header->len) < PP2_HEADER_LEN_INET) { + verbose(VERB_OPS, "proxy_protocol: header too short for IPv4 address"); + return 0; + } addr->sin_family = AF_INET; addr->sin_addr.s_addr = header->addr.addr4.src_addr; addr->sin_port = header->addr.addr4.src_port; @@ -963,6 +971,10 @@ static int consume_pp2_header(struct sld { struct sockaddr_in6* addr = (struct sockaddr_in6*)&rep->client_addr; + if(ntohs(header->len) < PP2_HEADER_LEN_INET6) { + verbose(VERB_OPS, "proxy_protocol: header too short for IPv6 address"); + return 0; + } memset(addr, 0, sizeof(*addr)); addr->sin6_family = AF_INET6; memcpy(&addr->sin6_addr, @@ -1827,7 +1839,6 @@ doq_send_retry(struct comm_point* c, str char host[256], port[32]; struct ngtcp2_cid scid; uint8_t token[NGTCP2_CRYPTO_MAX_RETRY_TOKENLEN]; - ngtcp2_tstamp ts; ngtcp2_ssize tokenlen, ret; if(!doq_print_addr_port(&paddr->addr, paddr->addrlen, host, @@ -1841,12 +1852,10 @@ doq_send_retry(struct comm_point* c, str scid.datalen = c->doq_socket->sv_scidlen; doq_cid_randfill(&scid, scid.datalen, c->doq_socket->rnd); - ts = doq_get_timestamp_nanosec(); - tokenlen = ngtcp2_crypto_generate_retry_token(token, c->doq_socket->static_secret, c->doq_socket->static_secret_len, hd->version, (void*)&paddr->addr, paddr->addrlen, &scid, - &hd->dcid, ts); + &hd->dcid, doq_get_timestamp_nanosec()); if(tokenlen < 0) { log_err("ngtcp2_crypto_generate_retry_token failed: %s", ngtcp2_strerror(tokenlen)); @@ -1895,13 +1904,11 @@ doq_verify_retry_token(struct comm_point struct ngtcp2_cid* ocid, struct ngtcp2_pkt_hd* hd) { char host[256], port[32]; - ngtcp2_tstamp ts; if(!doq_print_addr_port(&paddr->addr, paddr->addrlen, host, sizeof(host), port, sizeof(port))) { log_err("doq_verify_retry_token failed"); return 0; } - ts = doq_get_timestamp_nanosec(); verbose(VERB_ALGO, "doq: verifying retry token from %s %s", host, port); if(ngtcp2_crypto_verify_retry_token(ocid, @@ -1913,7 +1920,7 @@ doq_verify_retry_token(struct comm_point c->doq_socket->static_secret, c->doq_socket->static_secret_len, hd->version, (void*)&paddr->addr, paddr->addrlen, &hd->dcid, - 10*NGTCP2_SECONDS, ts) != 0) { + 10*NGTCP2_SECONDS, doq_get_timestamp_nanosec()) != 0) { verbose(VERB_ALGO, "doq: could not verify retry token " "from %s %s", host, port); return 0; @@ -1928,13 +1935,11 @@ doq_verify_token(struct comm_point* c, s struct ngtcp2_pkt_hd* hd) { char host[256], port[32]; - ngtcp2_tstamp ts; if(!doq_print_addr_port(&paddr->addr, paddr->addrlen, host, sizeof(host), port, sizeof(port))) { log_err("doq_verify_token failed"); return 0; } - ts = doq_get_timestamp_nanosec(); verbose(VERB_ALGO, "doq: verifying token from %s %s", host, port); if(ngtcp2_crypto_verify_regular_token( #ifdef HAVE_STRUCT_NGTCP2_PKT_HD_TOKENLEN @@ -1944,7 +1949,7 @@ doq_verify_token(struct comm_point* c, s #endif c->doq_socket->static_secret, c->doq_socket->static_secret_len, (void*)&paddr->addr, paddr->addrlen, 3600*NGTCP2_SECONDS, - ts) != 0) { + doq_get_timestamp_nanosec()) != 0) { verbose(VERB_ALGO, "doq: could not verify token from %s %s", host, port); return 0; @@ -2171,6 +2176,7 @@ doq_pickup_timer(struct comm_point* c) { struct doq_timer* t; struct timeval tv; + ngtcp2_tstamp ts = 0; int have_time = 0; memset(&tv, 0, sizeof(tv)); @@ -2180,27 +2186,24 @@ doq_pickup_timer(struct comm_point* c) t->worker_doq_socket == c->doq_socket) { /* pick up this element */ t->worker_doq_socket = c->doq_socket; + memcpy(&tv, &t->time_real, sizeof(tv)); + ts = t->time_mono; have_time = 1; - memcpy(&tv, &t->time, sizeof(tv)); break; } } lock_rw_unlock(&c->doq_socket->table->lock); - + c->doq_socket->marked_time = ts; if(have_time) { struct timeval rel; timeval_subtract(&rel, &tv, c->doq_socket->now_tv); comm_timer_set(c->doq_socket->timer, &rel); - memcpy(&c->doq_socket->marked_time, &tv, - sizeof(c->doq_socket->marked_time)); verbose(VERB_ALGO, "doq pickup timer at %d.%6.6d in %d.%6.6d", (int)tv.tv_sec, (int)tv.tv_usec, (int)rel.tv_sec, (int)rel.tv_usec); } else { if(comm_timer_is_set(c->doq_socket->timer)) comm_timer_disable(c->doq_socket->timer); - memset(&c->doq_socket->marked_time, 0, - sizeof(c->doq_socket->marked_time)); verbose(VERB_ALGO, "doq timer disabled"); } } @@ -2213,13 +2216,14 @@ doq_done_setup_timer_and_write(struct co uint8_t cid[NGTCP2_MAX_CIDLEN]; rbnode_type* node; struct timeval new_tv; + ngtcp2_tstamp new_ts; int write_change = 0, timer_change = 0; /* No longer in callbacks, so the pointer to doq_socket is back * to NULL. */ conn->doq_socket = NULL; - if(doq_conn_check_timer(conn, &new_tv)) + if(doq_conn_check_timer(conn, &new_tv, &new_ts)) timer_change = 1; if( (conn->write_interest && !conn->on_write_list) || (!conn->write_interest && conn->on_write_list)) @@ -2265,7 +2269,7 @@ doq_done_setup_timer_and_write(struct co } if(timer_change) { doq_timer_set(c->doq_socket->table, &conn->timer, - c->doq_socket, &new_tv); + c->doq_socket, &new_tv, new_ts); } lock_rw_unlock(&c->doq_socket->table->lock); lock_basic_unlock(&conn->lock); @@ -2429,7 +2433,7 @@ doq_write_blocked_pkt(struct comm_point* return 1; } -/** doq find a timer that timeouted and return the conn, locked. */ +/** doq find a timer that timed out and return the conn, locked. */ static struct doq_conn* doq_timer_timeout_conn(struct doq_server_socket* doq_socket) { @@ -2442,7 +2446,7 @@ doq_timer_timeout_conn(struct doq_server conn = t->conn; /* If now < timer then no further timeouts in tree. */ - if(timeval_smaller(doq_socket->now_tv, &t->time)) { + if(timeval_smaller(doq_socket->now_tv, &t->time_real)) { lock_rw_unlock(&doq_socket->table->lock); return NULL; } @@ -2465,11 +2469,11 @@ doq_timer_erase_marker(struct doq_server { struct doq_timer* t; lock_rw_wrlock(&doq_socket->table->lock); - t = doq_timer_find_time(doq_socket->table, &doq_socket->marked_time); + t = doq_timer_find_time(doq_socket->table, doq_socket->marked_time); if(t && t->worker_doq_socket == doq_socket) t->worker_doq_socket = NULL; lock_rw_unlock(&doq_socket->table->lock); - memset(&doq_socket->marked_time, 0, sizeof(doq_socket->marked_time)); + doq_socket->marked_time = 0; } void @@ -2723,6 +2727,7 @@ doq_server_socket_create(struct doq_tabl { size_t doq_buffer_size = 4096; /* bytes buffer size, for one packet. */ struct doq_server_socket* doq_socket; + log_assert(table != NULL); doq_socket = calloc(1, sizeof(*doq_socket)); if(!doq_socket) { return NULL; @@ -2775,7 +2780,7 @@ doq_server_socket_create(struct doq_tabl free(doq_socket); return NULL; } - memset(&doq_socket->marked_time, 0, sizeof(doq_socket->marked_time)); + doq_socket->marked_time = 0; comm_base_timept(base, &doq_socket->now_tt, &doq_socket->now_tv); doq_socket->cfg = cfg; return doq_socket; @@ -2804,6 +2809,7 @@ doq_lookup_repinfo(struct doq_table* tab { struct doq_conn* conn; struct doq_conn_key key; + log_assert(table != NULL); doq_conn_key_from_repinfo(&key, repinfo); lock_rw_rdlock(&table->lock); conn = doq_conn_find(table, &key.paddr.addr, @@ -2938,6 +2944,8 @@ setup_tcp_handler(struct comm_point* c, c->tcp_is_reading = 1; c->tcp_byte_count = 0; c->tcp_keepalive = 0; + /* reset to configured value before applying load-based reduction */ + c->tcp_timeout_msec = c->tcp_parent->tcp_timeout_msec; /* if more than half the tcp handlers are in use, use a shorter * timeout for this TCP connection, we need to make space for * other connections to be able to get attention */ @@ -2973,6 +2981,62 @@ void comm_base_handle_slow_accept(int AT } } +/** out of resources in the accept path: pause all listening for + * NETEVENT_SLOW_ACCEPT_TIME and re-arm via comm_base_handle_slow_accept. + * + * If the routine fails, the socket is accepted and then closed, draining it + * from the waiting list of connections to be accepted. + * @param c: the comm point that is a listening socket. + * @param msec: if 0: uses the slow accept time. Otherwise, sets the time + * to wait. + */ +static void +comm_point_slow_accept(struct comm_point* c, int msec) +{ + struct comm_base* b = c->ev->base; + struct timeval tv; + struct ub_event* slowev; + if(!b->stop_accept) + return; + if(b->eb->slow_accept_enabled) + return; + /* Allocate the event */ + slowev = ub_event_new(b->eb->base, -1, UB_EV_TIMEOUT, + comm_base_handle_slow_accept, b); + if(!slowev) { + /* The slow accept was not enabled yet, to handle + * the allocation failure, instead drain the incoming + * connection. */ + int new_fd = accept(c->fd, NULL, NULL); + if(new_fd != -1) { + verbose(VERB_ALGO, "slow accept: event_new failed, " + "drop connection"); + sock_close(new_fd); + } + return; + } + ub_comm_base_now(b); + if(b->eb->last_slow_log+SLOW_LOG_TIME <= b->eb->secs) { + b->eb->last_slow_log = b->eb->secs; + verbose(VERB_OPS, "out of resources on accept, " + "slow down accept for %d msec", + NETEVENT_SLOW_ACCEPT_TIME); + } + b->eb->slow_accept_enabled = 1; + fptr_ok(fptr_whitelist_stop_accept(b->stop_accept)); + (*b->stop_accept)(b->cb_arg); + /* set timeout, no mallocs */ + if(msec == 0) + msec = NETEVENT_SLOW_ACCEPT_TIME; + tv.tv_sec = msec/1000; + tv.tv_usec = (msec%1000)*1000; + b->eb->slow_accept = slowev; + if(ub_event_add(b->eb->slow_accept, &tv) != 0) { + /* we do not want to log here, + * error: "event_add failed." */ + } +} + int comm_point_perform_accept(struct comm_point* c, struct sockaddr_storage* addr, socklen_t* addrlen) { @@ -3006,6 +3070,14 @@ int comm_point_perform_accept(struct com if(c->ev->base->stop_accept) { struct comm_base* b = c->ev->base; struct timeval tv; + struct ub_event* slowev = ub_event_new( + b->eb->base, -1, UB_EV_TIMEOUT, + comm_base_handle_slow_accept, b); + if(!slowev) { + verbose(VERB_ALGO, "slow accept: " + "event_new failed"); + return -1; + } verbose(VERB_ALGO, "out of file descriptors: " "slow accept"); ub_comm_base_now(b); @@ -3025,15 +3097,8 @@ int comm_point_perform_accept(struct com /* set timeout, no mallocs */ tv.tv_sec = NETEVENT_SLOW_ACCEPT_TIME/1000; tv.tv_usec = (NETEVENT_SLOW_ACCEPT_TIME%1000)*1000; - b->eb->slow_accept = ub_event_new(b->eb->base, - -1, UB_EV_TIMEOUT, - comm_base_handle_slow_accept, b); - if(b->eb->slow_accept == NULL) { - /* we do not want to log here, because - * that would spam the logfiles. - * error: "event_base_set failed." */ - } - else if(ub_event_add(b->eb->slow_accept, &tv) + b->eb->slow_accept = slowev; + if(ub_event_add(b->eb->slow_accept, &tv) != 0) { /* we do not want to log here, * error: "event_add failed." */ @@ -3165,6 +3230,26 @@ static int http2_submit_settings(struct } #endif /* HAVE_NGHTTP2 */ +/** Clear http2 stream mesh states */ +static void http2_session_clear_meshstate(struct http2_session* h2_session) +{ +#ifdef HAVE_NGHTTP2 + /* Since the session gets closed, remove the mesh state references. */ + struct http2_stream* h2_stream; + for(h2_stream = h2_session->first_stream; h2_stream; + h2_stream = h2_stream->next) { + if(h2_stream->mesh_state) { + mesh_state_remove_reply(h2_stream->mesh, + h2_stream->mesh_state, h2_session->c, + h2_stream, NULL); + h2_stream->mesh_state = NULL; + } + } +#else + (void)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, @@ -3172,7 +3257,7 @@ static void http2_stream_delete(struct h { if(h2_stream->mesh_state) { mesh_state_remove_reply(h2_stream->mesh, h2_stream->mesh_state, - h2_session->c); + h2_session->c, h2_stream, NULL); h2_stream->mesh_state = NULL; } http2_req_stream_clear(h2_stream); @@ -3214,6 +3299,13 @@ comm_point_tcp_accept_callback(int fd, s /* find free tcp handler. */ if(!c->tcp_free) { log_warn("accepted too many tcp, connections full"); + /* Wait for a short moment (say 50msec) so that other + * TCP connections can complete. Or timeout, at the busy + * timeout of about 200msec. That stops this routine from + * spinning endlessly, and gives time to complete the other + * requests. But it is not as slow as the 2000msec wait + * time for when the kernel is out of buffers. */ + comm_point_slow_accept(c, NETEVENT_SLOW_ACCEPT_QUEUE_TIME); return; } /* accept incoming connection. */ @@ -3235,6 +3327,7 @@ comm_point_tcp_accept_callback(int fd, s if(!c_hdl->h2_session || !http2_session_server_create(c_hdl->h2_session)) { log_warn("failed to create nghttp2"); + comm_point_slow_accept(c, 0); return; } if(!c_hdl->h2_session || @@ -3242,6 +3335,7 @@ comm_point_tcp_accept_callback(int fd, s log_warn("failed to submit http2 settings"); if(c_hdl->h2_session) http2_session_server_delete(c_hdl->h2_session); + comm_point_slow_accept(c, 0); return; } if(!c->ssl) { @@ -3258,11 +3352,12 @@ comm_point_tcp_accept_callback(int fd, s comm_point_tcp_handle_callback, c_hdl); } if(!c_hdl->ev->ev) { - log_warn("could not ub_event_new, dropped tcp"); + log_warn("could not ub_event_new, for new tcp"); #ifdef HAVE_NGHTTP2 if(c_hdl->type == comm_http && c_hdl->h2_session) http2_session_server_delete(c_hdl->h2_session); #endif + comm_point_slow_accept(c, 0); return; } log_assert(fd != -1); @@ -3276,6 +3371,10 @@ comm_point_tcp_accept_callback(int fd, s #endif return; } + /* move per-netblock TCP-connection-limit handle to the handler so that + * comm_point_close() on the handler decrements the count on close */ + c_hdl->tcl_addr = c->tcl_addr; + c->tcl_addr = NULL; /* Copy remote_address to client_address. * Simplest way/time for streams to do that. */ c_hdl->repinfo.client_addrlen = c_hdl->repinfo.remote_addrlen; @@ -4178,8 +4277,8 @@ recv_error: if(errno == EINTR || errno == EAGAIN) return 1; #ifdef ECONNRESET - if(errno == ECONNRESET && verbosity < 2) - return 0; /* silence reset by peer */ + if(errno == ECONNRESET && verbosity < 2) + return 0; /* silence reset by peer */ #endif if(recv_initial) { #ifdef ECONNREFUSED @@ -4546,6 +4645,10 @@ comm_point_tcp_handle_write(int fd, stru static int tcp_req_info_read_again(int fd, struct comm_point* c) { + /* One event-loop visit drains at most this many pipelined queries; + * the rest is re-queued, so that other file descriptors get + * serviced in between. */ + int budget = NUM_TCP_PER_SELECT; while(c->tcp_req_info->read_again) { int r; c->tcp_req_info->read_again = 0; @@ -4562,6 +4665,16 @@ tcp_req_info_read_again(int fd, struct c } return 0; } + if(--budget <= 0 && c->tcp_req_info->read_again) { + /* Defer the rest of the drain to the next loop turn. + * This uses a zero delay timer. For TLS the undrained + * remainder sits in OpenSSL's user-space buffer. */ + struct timeval tv; + memset(&tv, 0, sizeof(tv)); + verbose(VERB_ALGO, "Defer tcp_req_info read again"); + comm_timer_set(c->tcp_req_info->read_again_timer, &tv); + return 1; + } } return 1; } @@ -4575,6 +4688,7 @@ tcp_more_read_again(int fd, struct comm_ /* this continues until the read routines get EAGAIN or so, * and thus does not call the callback, and the bool is 0 */ int* moreread = c->tcp_more_read_again; + int budget = NUM_TCP_PER_SELECT; while(moreread && *moreread) { *moreread = 0; if(!comm_point_tcp_handle_read(fd, c, 0)) { @@ -4587,6 +4701,30 @@ tcp_more_read_again(int fd, struct comm_ } return; } + if(--budget <= 0 && *moreread) { + /* Defer the rest of the drain to the next loop turn. + * This uses a zero delay timer. For TLS the undrained + * remainder sits in OpenSSL's user-space buffer. */ + struct timeval tv; + memset(&tv, 0, sizeof(tv)); + if(!c->tcp_more_read_again_timer) { + c->tcp_more_read_again_timer = comm_timer_create(c->ev->base, tcp_more_read_again_cb, c); + if(!c->tcp_more_read_again_timer) { + log_err("out of memory for tcp more read again timer"); + reclaim_tcp_handler(c); + if(!c->tcp_do_close) { + fptr_ok(fptr_whitelist_comm_point( + c->callback)); + (void)(*c->callback)(c, c->cb_arg, + NETEVENT_CLOSED, NULL); + } + return; + } + } + verbose(VERB_ALGO, "Defer more read again"); + comm_timer_set(c->tcp_more_read_again_timer, &tv); + return; + } } } @@ -4615,6 +4753,23 @@ tcp_more_write_again(int fd, struct comm } void +tcp_read_again_cb(void* arg) +{ + struct tcp_req_info* req = (struct tcp_req_info*)arg; + verbose(VERB_ALGO, "tcp_read_again_cb"); + if(!tcp_req_info_read_again(req->cp->fd, req->cp)) + return; +} + +void +tcp_more_read_again_cb(void* arg) +{ + struct comm_point* c = (struct comm_point*)arg; + verbose(VERB_ALGO, "tcp_more_read_again_cb"); + tcp_more_read_again(c->fd, c); +} + +void comm_point_tcp_handle_callback(int fd, short event, void* arg) { struct comm_point* c = (struct comm_point*)arg; @@ -4868,8 +5023,17 @@ http_process_initial_header(struct comm_ return 0; } } else if(strncasecmp(line, "Content-Length: ", 16) == 0) { - if(!c->http_is_chunked) - c->tcp_byte_count = (size_t)atoi(line+16); + if(!c->http_is_chunked) { + char* end = NULL; + long long cl; + errno = 0; + cl = strtoll(line+16, &end, 10); + if(end == line+16 || errno != 0 || cl < 0) { + verbose(VERB_ALGO, "http invalid Content-Length: " ARG_LL "d", cl); + return 0; /* reject */ + } + c->tcp_byte_count = (size_t)cl; + } } else if(strncasecmp(line, "Transfer-Encoding: chunked", 19+7) == 0) { c->tcp_byte_count = 0; c->http_is_chunked = 1; @@ -4925,9 +5089,15 @@ http_process_chunk_header(struct comm_po if(c->http_in_chunk_headers == 1) { /* read chunked start line */ char* end = NULL; - c->tcp_byte_count = (size_t)strtol(line, &end, 16); - if(end == line) + long chunk_sz; + errno = 0; + chunk_sz = strtol(line, &end, 16); + if(end == line || errno != 0 || chunk_sz < 0) { + verbose(VERB_ALGO, "http invalid chunk size: %ld", + chunk_sz); return 0; + } + c->tcp_byte_count = (size_t)chunk_sz; c->http_in_chunk_headers = 0; /* remove header text from front of buffer */ http_moveover_buffer(c->buffer); @@ -5005,6 +5175,14 @@ http_chunked_segment(struct comm_point* c->http_stored = 0; sldns_buffer_skip(c->buffer, (ssize_t)c->tcp_byte_count); sldns_buffer_clear(c->http_temp); + if(sldns_buffer_remaining(c->buffer) > + sldns_buffer_capacity(c->http_temp)) { + verbose(VERB_OPS, "http chunked: surplus %d exceeds " + "temp buffer %d", (int)sldns_buffer_remaining( + c->buffer), (int)sldns_buffer_capacity( + c->http_temp)); + return 0; + } sldns_buffer_write(c->http_temp, sldns_buffer_current(c->buffer), sldns_buffer_remaining(c->buffer)); @@ -5335,6 +5513,13 @@ comm_point_http_handle_read(int fd, stru if(c->http_in_headers || c->http_in_chunk_headers) { /* if header is done, process the header */ if(!http_header_done(c->buffer)) { + if(sldns_buffer_limit(c->buffer) == + sldns_buffer_capacity(c->buffer)) { + verbose(VERB_OPS, "http header line " + "exceeds %d bytes, transfer " + "failed", (int)sldns_buffer_capacity(c->buffer)); + return 0; + } /* copy remaining data to front of buffer * and set rest for writing into it */ http_moveover_buffer(c->buffer); @@ -5883,6 +6068,7 @@ comm_point_create_doq(struct comm_base * struct comm_point* c = (struct comm_point*)calloc(1, sizeof(struct comm_point)); short evbits; + log_assert(table != NULL); if(!c) return NULL; c->ev = (struct internal_event*)calloc(1, @@ -6025,7 +6211,7 @@ comm_point_create_tcp_handler(struct com c->pp2_enabled = parent->pp2_enabled; c->pp2_header_state = pp2_header_none; if(spoolbuf) { - c->tcp_req_info = tcp_req_info_create(spoolbuf); + c->tcp_req_info = tcp_req_info_create(base, spoolbuf); if(!c->tcp_req_info) { log_err("could not create tcp commpoint"); sldns_buffer_free(c->buffer); @@ -6574,7 +6760,10 @@ comm_point_close(struct comm_point* c) c->event_added = 0; } } - tcl_close_connection(c->tcl_addr); + if(c->tcl_addr) { + tcl_close_connection(c->tcl_addr); + c->tcl_addr = NULL; + } if(c->tcp_req_info) tcp_req_info_clear(c->tcp_req_info); if(c->h2_session) @@ -6584,6 +6773,9 @@ comm_point_close(struct comm_point* c) *c->tcp_more_read_again = 0; if(c->tcp_more_write_again && *c->tcp_more_write_again) *c->tcp_more_write_again = 0; + if(c->tcp_more_read_again_timer && + comm_timer_is_set(c->tcp_more_read_again_timer)) + comm_timer_disable(c->tcp_more_read_again_timer); /* close fd after removing from event lists, or epoll.. is messed up */ if(c->fd != -1 && !c->do_not_close) { @@ -6623,6 +6815,7 @@ comm_point_delete(struct comm_point* c) free(c->tcp_handlers); } free(c->timeout); + comm_timer_delete(c->tcp_more_read_again_timer); if(c->type == comm_tcp || c->type == comm_local || c->type == comm_http) { sldns_buffer_free(c->buffer); #ifdef USE_DNSCRYPT @@ -6667,7 +6860,9 @@ comm_point_send_reply(struct comm_reply log_assert(repinfo && repinfo->c); #ifdef USE_DNSCRYPT buffer = repinfo->c->dnscrypt_buffer; - if(!dnsc_handle_uncurved_request(repinfo)) { + if(!dnsc_handle_uncurved_request(repinfo, + repinfo->c->tcp_req_info? + repinfo->c->tcp_req_info->spool_buffer:repinfo->c->buffer)) { return; } #else @@ -6728,7 +6923,6 @@ comm_point_send_reply(struct comm_reply tcp_req_info_send_reply(repinfo->c->tcp_req_info); } else if(repinfo->c->use_h2) { if(!http2_submit_dns_response(repinfo->c->h2_session)) { - comm_point_drop_reply(repinfo); return; } repinfo->c->h2_stream = NULL; @@ -6762,6 +6956,7 @@ comm_point_drop_reply(struct comm_reply* if(repinfo->c->type == comm_http) { if(repinfo->c->h2_session) { repinfo->c->h2_session->is_drop = 1; + http2_session_clear_meshstate(repinfo->c->h2_session); if(!repinfo->c->h2_session->postpone_drop) reclaim_http_handler(repinfo->c); return; Index: sbin/unwind/libunbound/util/netevent.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/netevent.h,v diff -u -p -r1.15 netevent.h --- sbin/unwind/libunbound/util/netevent.h 29 Sep 2025 14:53:38 -0000 1.15 +++ sbin/unwind/libunbound/util/netevent.h 21 Sep 2026 16:28:29 -0000 @@ -111,6 +111,8 @@ typedef int comm_point_callback_type(str /** timeout to slow accept calls when not possible, in msec. */ #define NETEVENT_SLOW_ACCEPT_TIME 2000 +/** timeout to slow accept calls when tcp queue is full, in msec. */ +#define NETEVENT_SLOW_ACCEPT_QUEUE_TIME 50 /** timeout to slow down log print, so it does not spam the logs, in sec */ #define SLOW_LOG_TIME 10 /** for doq, the maximum dcid length, in ngtcp2 it is 20. */ @@ -187,6 +189,8 @@ struct comm_reply { /** port number for doq */ int doq_srcport; #endif /* HAVE_NGTCP2 */ + /** The doq stream to register mesh states to. */ + struct doq_stream* doq_stream; }; /** @@ -380,6 +384,9 @@ struct comm_point { * Or leave NULL if it is not used at all. */ int* tcp_more_write_again; + /** resume timer for tcp_more_read_again */ + struct comm_timer* tcp_more_read_again_timer; + /** if set, read/write completes: read/write state of tcp is toggled. buffer reset/bytecount reset. @@ -1093,8 +1100,10 @@ struct doq_server_socket { struct doq_pkt_addr* blocked_paddr; /** timer for this worker on this comm_point to wait on. */ struct comm_timer* timer; +#ifdef HAVE_NGTCP2 /** the timer that is marked by the doq_socket as waited on. */ - struct timeval marked_time; + ngtcp2_tstamp marked_time; +#endif /** the current time for use by time functions, time_t. */ time_t* now_tt; /** the current time for use by time functions, timeval. */ @@ -1126,6 +1135,12 @@ void doq_send_pkt(struct comm_point* c, /** doq timer callback function. */ void doq_timer_cb(void* arg); + +/** tcp read again callback function. For tcp req info listen. */ +void tcp_read_again_cb(void* arg); + +/** tcp more read again callback function. For outside network. */ +void tcp_more_read_again_cb(void* arg); /** * This routine is published for checks and tests, and is only used internally. Index: sbin/unwind/libunbound/util/proxy_protocol.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/proxy_protocol.c,v diff -u -p -r1.3 proxy_protocol.c --- sbin/unwind/libunbound/util/proxy_protocol.c 5 Sep 2024 08:22:47 -0000 1.3 +++ sbin/unwind/libunbound/util/proxy_protocol.c 21 Sep 2026 16:28:29 -0000 @@ -185,14 +185,23 @@ pp2_read_header(uint8_t* buf, size_t buf (header->ver_cmd & 0xF) != PP2_CMD_PROXY) { return PP_PARSE_UNKNOWN_CMD; } - /* Check for supported family and protocol */ - if(header->fam_prot != PP2_UNSPEC_UNSPEC && - header->fam_prot != PP2_INET_STREAM && - header->fam_prot != PP2_INET_DGRAM && - header->fam_prot != PP2_INET6_STREAM && - header->fam_prot != PP2_INET6_DGRAM && - header->fam_prot != PP2_UNIX_STREAM && - header->fam_prot != PP2_UNIX_DGRAM) { + /* Check for supported family and protocol, and that len covers + * the per-family address block (proxy-protocol.txt s2.2). */ + switch(header->fam_prot) { + case PP2_UNSPEC_UNSPEC: + break; + case PP2_INET_STREAM: + case PP2_INET_DGRAM: + if(ntohs(header->len) < PP2_HEADER_LEN_INET) + return PP_PARSE_SIZE; + break; + case PP2_INET6_STREAM: + case PP2_INET6_DGRAM: + if(ntohs(header->len) < PP2_HEADER_LEN_INET6) + return PP_PARSE_SIZE; + break; + default: + /* PP2_UNIX_STREAM, PP2_UNIX_DGRAM, others. */ return PP_PARSE_UNKNOWN_FAM_PROT; } /* We have a correct header */ Index: sbin/unwind/libunbound/util/proxy_protocol.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/proxy_protocol.h,v diff -u -p -r1.2 proxy_protocol.h --- sbin/unwind/libunbound/util/proxy_protocol.h 13 Apr 2024 13:58:35 -0000 1.2 +++ sbin/unwind/libunbound/util/proxy_protocol.h 21 Sep 2026 16:28:29 -0000 @@ -54,6 +54,15 @@ /** PROXYv2 version (protocol value) */ #define PP2_VERSION 0x2 +/** PROXYv2 minimum header.len value for TCP/UDP over IPv4 */ +#define PP2_HEADER_LEN_INET 12 + +/** PROXYv2 minimum header.len value for TCP/UDP over IPv6 */ +#define PP2_HEADER_LEN_INET6 36 + +/** PROXYv2 minimum header.len value for TCP/UDP over AF_UNIX */ +#define PP2_HEADER_LEN_UNIX 216 + /** * PROXYv2 command (protocol value). */ Index: sbin/unwind/libunbound/util/timehist.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/timehist.h,v diff -u -p -r1.1 timehist.h --- sbin/unwind/libunbound/util/timehist.h 23 Jan 2019 13:05:27 -0000 1.1 +++ sbin/unwind/libunbound/util/timehist.h 21 Sep 2026 16:28:29 -0000 @@ -42,6 +42,10 @@ #ifndef UTIL_TIMEHIST_H #define UTIL_TIMEHIST_H +#ifdef __QNX__ +/* For struct timeval */ +#include +#endif /* __QNX__ */ /** Number of buckets in a histogram */ #define NUM_BUCKETS_HIST 40 Index: sbin/unwind/libunbound/util/tube.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/tube.c,v diff -u -p -r1.6 tube.c --- sbin/unwind/libunbound/util/tube.c 14 Sep 2025 15:16:53 -0000 1.6 +++ sbin/unwind/libunbound/util/tube.c 21 Sep 2026 16:28:29 -0000 @@ -145,6 +145,20 @@ void tube_remove_bg_write(struct tube* t } } +/** Drain the pipe of bytes. */ +static void +fd_drain(int fd, uint32_t len) +{ + uint8_t discard[256]; + uint32_t remaining = len; + while(remaining > 0) { + ssize_t n = read(fd, discard, + remaining < sizeof(discard) ? remaining : sizeof(discard)); + if(n <= 0) break; + remaining -= (uint32_t)n; + } +} + int tube_handle_listen(struct comm_point* c, void* arg, int error, struct comm_reply* ATTR_UNUSED(reply_info)) @@ -184,6 +198,9 @@ tube_handle_listen(struct comm_point* c, tube->cmd_msg = (uint8_t*)calloc(1, tube->cmd_len); if(!tube->cmd_msg) { log_err("malloc failure"); + /* Drain the remaining bytes, since they belong to this + * message. The next message starts after it. */ + fd_drain(c->fd, tube->cmd_len); tube->cmd_read = 0; return 0; } @@ -374,6 +391,9 @@ int tube_read_msg(struct tube* tube, uin *buf = (uint8_t*)malloc(*len); if(!*buf) { log_err("tube read out of memory"); + /* Drain the remaining bytes, since they belong to this + * message. The next message starts after it. */ + fd_drain(fd, *len); (void)fd_set_nonblock(fd); return 0; } Index: sbin/unwind/libunbound/util/data/dname.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/data/dname.c,v diff -u -p -r1.6 dname.c --- sbin/unwind/libunbound/util/data/dname.c 29 Sep 2025 14:53:38 -0000 1.6 +++ sbin/unwind/libunbound/util/data/dname.c 21 Sep 2026 16:28:29 -0000 @@ -192,34 +192,34 @@ pkt_dname_len(sldns_buffer* pkt) while(1) { /* read next label */ if(sldns_buffer_remaining(pkt) < 1) - return 0; + goto fail; labellen = sldns_buffer_read_u8(pkt); if(LABEL_IS_PTR(labellen)) { /* compression ptr */ uint16_t ptr; if(sldns_buffer_remaining(pkt) < 1) - return 0; + goto fail; ptr = PTR_OFFSET(labellen, sldns_buffer_read_u8(pkt)); if(ptrcount++ > MAX_COMPRESS_PTRS) - return 0; /* loop! */ + goto fail; /* loop! */ if(sldns_buffer_limit(pkt) <= ptr) - return 0; /* out of bounds! */ + goto fail; /* out of bounds! */ if(!endpos) endpos = sldns_buffer_position(pkt); sldns_buffer_set_position(pkt, ptr); } else { /* label contents */ if(labellen > 0x3f) - return 0; /* label too long */ + goto fail; /* label too long */ len += 1 + labellen; if(len > LDNS_MAX_DOMAINLEN) - return 0; + goto fail; if(labellen == 0) { /* end of dname */ break; } if(sldns_buffer_remaining(pkt) < labellen) - return 0; + goto fail; sldns_buffer_skip(pkt, (ssize_t)labellen); } } @@ -227,6 +227,13 @@ pkt_dname_len(sldns_buffer* pkt) sldns_buffer_set_position(pkt, endpos); return len; +fail: + /* Restore the position on failure too: callers (rdata_copy) compute + * the consumed field length from the buffer position and must not + * see a partial walk of a name that failed to parse. */ + if(endpos) + sldns_buffer_set_position(pkt, endpos); + return 0; } int Index: sbin/unwind/libunbound/util/data/msgencode.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/data/msgencode.c,v diff -u -p -r1.10 msgencode.c --- sbin/unwind/libunbound/util/data/msgencode.c 29 Sep 2025 14:53:38 -0000 1.10 +++ sbin/unwind/libunbound/util/data/msgencode.c 21 Sep 2026 16:28:29 -0000 @@ -352,7 +352,6 @@ compress_any_dname(uint8_t* dname, sldns (p = compress_tree_lookup(tree, dname, labs, &insertpt))) { if(!write_compressed_dname(pkt, dname, labs, p)) return RETVAL_TRUNC; - (*compress_count)++; } else { if(!dname_buffer_write(pkt, dname)) return RETVAL_TRUNC; @@ -360,6 +359,7 @@ compress_any_dname(uint8_t* dname, sldns if(*compress_count < MAX_COMPRESSION_PER_MESSAGE && !compress_tree_store(dname, labs, pos, region, p, insertpt)) return RETVAL_OUTMEM; + (*compress_count)++; return RETVAL_OK; } @@ -496,10 +496,18 @@ packed_rrset_encode(struct ub_packed_rrs return r; sldns_buffer_write(pkt, &key->rk.type, 2); sldns_buffer_write(pkt, &key->rk.rrset_class, 2); - if(data->rr_ttl[j] < adjust) + if(key->rk.flags & PACKED_RRSET_UPSTREAM_0TTL) { + sldns_buffer_write_u32(pkt, 0); + } else if(adjust == 0) { + sldns_buffer_write_u32(pkt, data->rr_ttl[j]); + } else if(TTL_IS_EXPIRED(data->rr_ttl[j], adjust)) { sldns_buffer_write_u32(pkt, - SERVE_EXPIRED?SERVE_EXPIRED_REPLY_TTL:0); - else sldns_buffer_write_u32(pkt, data->rr_ttl[j]-adjust); + EXPIRED_REPLY_TTL_CALC( + data->rr_ttl[j], data->ttl_add)); + } else { + sldns_buffer_write_u32(pkt, + data->rr_ttl[j] - adjust); + } if(c) { if((r=compress_rdata(pkt, data->rr_data[j], data->rr_len[j], region, tree, c, @@ -533,10 +541,18 @@ packed_rrset_encode(struct ub_packed_rrs } sldns_buffer_write_u16(pkt, LDNS_RR_TYPE_RRSIG); sldns_buffer_write(pkt, &key->rk.rrset_class, 2); - if(data->rr_ttl[i] < adjust) + if(key->rk.flags & PACKED_RRSET_UPSTREAM_0TTL) { + sldns_buffer_write_u32(pkt, 0); + } else if(adjust == 0) { + sldns_buffer_write_u32(pkt, data->rr_ttl[i]); + } else if(TTL_IS_EXPIRED(data->rr_ttl[i], adjust)) { sldns_buffer_write_u32(pkt, - SERVE_EXPIRED?SERVE_EXPIRED_REPLY_TTL:0); - else sldns_buffer_write_u32(pkt, data->rr_ttl[i]-adjust); + EXPIRED_REPLY_TTL_CALC( + data->rr_ttl[i], data->ttl_add)); + } else { + sldns_buffer_write_u32(pkt, + data->rr_ttl[i] - adjust); + } /* rrsig rdata cannot be compressed, perform 100+ byte * memcopy. */ sldns_buffer_write(pkt, data->rr_data[i], @@ -618,7 +634,7 @@ insert_query(struct query_info* qinfo, s size_t qname_len = qinfo->local_alias ? qinfo->local_alias->rrset->rk.dname_len : qinfo->qname_len; if(sldns_buffer_remaining(buffer) < - qinfo->qname_len+sizeof(uint16_t)*2) + qname_len+sizeof(uint16_t)*2) return RETVAL_TRUNC; /* buffer too small */ /* the query is the first name inserted into the tree */ if(!compress_tree_store(qname, dname_count_labels(qname), @@ -804,7 +820,7 @@ reply_info_encode(struct query_info* qin return 1; } -uint16_t +size_t calc_edns_field_size(struct edns_data* edns) { size_t rdatalen = 0; @@ -840,7 +856,7 @@ calc_edns_option_size(struct edns_data* } uint16_t -calc_ede_option_size(struct edns_data* edns, uint16_t* txt_size) +calc_ede_option_size(struct edns_data* edns, size_t* txt_size) { size_t rdatalen = 0; struct edns_option* opt; @@ -942,6 +958,10 @@ attach_edns_record_max_msg_sz(sldns_buff padding_option = opt; continue; } + if(sldns_buffer_position(pkt) + opt->opt_len + 4 > max_msg_sz) + break; /* no space for it */ + if(!sldns_buffer_available(pkt, 4 + opt->opt_len)) + break; sldns_buffer_write_u16(pkt, opt->opt_code); sldns_buffer_write_u16(pkt, opt->opt_len); if(opt->opt_len != 0) @@ -952,12 +972,18 @@ attach_edns_record_max_msg_sz(sldns_buff padding_option = opt; continue; } + if(sldns_buffer_position(pkt) + opt->opt_len + 4 > max_msg_sz) + break; /* no space for it */ + if(!sldns_buffer_available(pkt, 4 + opt->opt_len)) + break; sldns_buffer_write_u16(pkt, opt->opt_code); sldns_buffer_write_u16(pkt, opt->opt_len); if(opt->opt_len != 0) sldns_buffer_write(pkt, opt->opt_data, opt->opt_len); } - if (padding_option && edns->padding_block_size ) { + if (padding_option && edns->padding_block_size && + sldns_buffer_position(pkt)+4 <= max_msg_sz && + sldns_buffer_available(pkt, 4) /* if there is space for it */) { size_t pad_pos = sldns_buffer_position(pkt); size_t msg_sz = ((pad_pos + 3) / edns->padding_block_size + 1) * edns->padding_block_size; @@ -993,15 +1019,15 @@ attach_edns_record(sldns_buffer* pkt, st attach_edns_record_max_msg_sz(pkt, edns, edns->udp_size); } -int -reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep, +int +reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep, uint16_t id, uint16_t qflags, sldns_buffer* pkt, time_t timenow, - int cached, struct regional* region, uint16_t udpsize, + int cached, struct regional* region, uint16_t udpsize, struct edns_data* edns, int dnssec, int secure) { uint16_t flags; unsigned int attach_edns = 0; - uint16_t edns_field_size, ede_size, ede_txt_size; + size_t edns_field_size, ede_size, ede_txt_size; if(!cached || rep->authoritative) { /* original flags, copy RD and CD bits from query. */ @@ -1028,12 +1054,12 @@ reply_info_answer_encode(struct query_in * calculate sizes once here */ edns_field_size = calc_edns_field_size(edns); ede_size = calc_ede_option_size(edns, &ede_txt_size); - if(sldns_buffer_capacity(pkt) < udpsize) + if(sldns_buffer_capacity(pkt) < (size_t)udpsize) udpsize = sldns_buffer_capacity(pkt); if(!edns || !edns->edns_present) { attach_edns = 0; /* EDEs are optional, try to fit anything else before them */ - } else if(udpsize < LDNS_HEADER_SIZE + edns_field_size - ede_size) { + } else if((size_t)udpsize < (size_t)LDNS_HEADER_SIZE + edns_field_size - ede_size) { /* packet too small to contain edns, omit it. */ attach_edns = 0; } else { @@ -1047,13 +1073,13 @@ reply_info_answer_encode(struct query_in return 0; } if(attach_edns) { - if(udpsize >= sldns_buffer_limit(pkt) + edns_field_size) + if((size_t)udpsize >= sldns_buffer_limit(pkt) + edns_field_size) attach_edns_record_max_msg_sz(pkt, edns, udpsize); - else if(udpsize >= sldns_buffer_limit(pkt) + edns_field_size - ede_txt_size) { + else if((size_t)udpsize >= sldns_buffer_limit(pkt) + edns_field_size - ede_txt_size) { ede_trim_text(&edns->opt_list_inplace_cb_out); ede_trim_text(&edns->opt_list_out); attach_edns_record_max_msg_sz(pkt, edns, udpsize); - } else if(udpsize >= sldns_buffer_limit(pkt) + edns_field_size - ede_size) { + } else if((size_t)udpsize >= sldns_buffer_limit(pkt) + edns_field_size - ede_size) { edns_opt_list_remove(&edns->opt_list_inplace_cb_out, LDNS_EDNS_EDE); edns_opt_list_remove(&edns->opt_list_out, LDNS_EDNS_EDE); attach_edns_record_max_msg_sz(pkt, edns, udpsize); @@ -1103,9 +1129,11 @@ extended_error_encode(sldns_buffer* buf, sldns_buffer_write(buf, &flags, sizeof(uint16_t)); sldns_buffer_write(buf, &flags, sizeof(uint16_t)); if(qinfo) { - const uint8_t* qname = qinfo->local_alias ? + const uint8_t* qname = + (qinfo->local_alias && qinfo->local_alias->rrset) ? qinfo->local_alias->rrset->rk.dname : qinfo->qname; - size_t qname_len = qinfo->local_alias ? + size_t qname_len = + (qinfo->local_alias && qinfo->local_alias->rrset) ? qinfo->local_alias->rrset->rk.dname_len : qinfo->qname_len; if(sldns_buffer_current(buf) == qname) @@ -1115,22 +1143,30 @@ extended_error_encode(sldns_buffer* buf, sldns_buffer_write_u16(buf, qinfo->qclass); } sldns_buffer_flip(buf); - if(edns) { + if(edns && edns->edns_present) { + size_t edns_field_size, ede_size, ede_txt_size; struct edns_data es = *edns; es.edns_version = EDNS_ADVERTISED_VERSION; es.udp_size = EDNS_ADVERTISED_SIZE; es.ext_rcode = (uint8_t)(rcode >> 4); es.bits &= EDNS_DO; - if(sldns_buffer_limit(buf) + calc_edns_field_size(&es) > - edns->udp_size) { + /* EDEs are optional. If space is a concern try in order: + * - removing any EXTRA-TEXT fields from explicit EDEs, or + * - removing all EDEs, + * to see if EDNS can fit. */ + edns_field_size = calc_edns_field_size(&es); + ede_size = calc_ede_option_size(&es, &ede_txt_size); + if((size_t)edns->udp_size >= sldns_buffer_limit(buf) + edns_field_size) + attach_edns_record_max_msg_sz(buf, &es, edns->udp_size); + else if((size_t)edns->udp_size >= sldns_buffer_limit(buf) + edns_field_size - ede_txt_size) { + ede_trim_text(&es.opt_list_inplace_cb_out); + ede_trim_text(&es.opt_list_out); + attach_edns_record_max_msg_sz(buf, &es, edns->udp_size); + } else if((size_t)edns->udp_size >= sldns_buffer_limit(buf) + edns_field_size - ede_size) { edns_opt_list_remove(&es.opt_list_inplace_cb_out, LDNS_EDNS_EDE); edns_opt_list_remove(&es.opt_list_out, LDNS_EDNS_EDE); - if(sldns_buffer_limit(buf) + calc_edns_field_size(&es) > - edns->udp_size) { - return; - } + attach_edns_record_max_msg_sz(buf, &es, edns->udp_size); } - attach_edns_record(buf, &es); } } Index: sbin/unwind/libunbound/util/data/msgencode.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/data/msgencode.h,v diff -u -p -r1.4 msgencode.h --- sbin/unwind/libunbound/util/data/msgencode.h 29 Sep 2025 14:53:38 -0000 1.4 +++ sbin/unwind/libunbound/util/data/msgencode.h 21 Sep 2026 16:28:29 -0000 @@ -66,9 +66,9 @@ struct edns_data; * @param secure: if 1, the AD bit is set in the reply. * @return: 0 on error (server failure). */ -int reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep, +int reply_info_answer_encode(struct query_info* qinf, struct reply_info* rep, uint16_t id, uint16_t qflags, struct sldns_buffer* dest, time_t timenow, - int cached, struct regional* region, uint16_t udpsize, + int cached, struct regional* region, uint16_t udpsize, struct edns_data* edns, int dnssec, int secure); /** @@ -106,7 +106,7 @@ void qinfo_query_encode(struct sldns_buf * @param edns: edns data or NULL. * @return octets to reserve for EDNS. */ -uint16_t calc_edns_field_size(struct edns_data* edns); +size_t calc_edns_field_size(struct edns_data* edns); /** * Calculate the size of a specific EDNS option in packet. @@ -127,7 +127,7 @@ uint16_t calc_edns_option_size(struct ed * extra text. * @return octets the option will take up. */ -uint16_t calc_ede_option_size(struct edns_data* edns, uint16_t* txt_size); +uint16_t calc_ede_option_size(struct edns_data* edns, size_t* txt_size); /** * Attach EDNS record to buffer. Buffer has complete packet. There must Index: sbin/unwind/libunbound/util/data/msgparse.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/data/msgparse.c,v diff -u -p -r1.9 msgparse.c --- sbin/unwind/libunbound/util/data/msgparse.c 5 Sep 2024 08:22:47 -0000 1.9 +++ sbin/unwind/libunbound/util/data/msgparse.c 21 Sep 2026 16:28:29 -0000 @@ -53,6 +53,8 @@ #include "sldns/parseutil.h" #include "sldns/wire2str.h" +#define MAX_PARSED_EDNS_OPTIONS 100 + /** smart comparison of (compressed, valid) dnames from packet */ static int smart_compare(sldns_buffer* pkt, uint8_t* dnow, @@ -685,6 +687,9 @@ calc_size(sldns_buffer* pkt, uint16_t ty } rdf++; } + /* rdata ended before all _dname_count names were seen */ + if(count != 0) + return 0; /* the rdata is too short. */ } /* remaining rdata */ rr->size += pkt_len; @@ -950,6 +955,7 @@ parse_edns_options_from_query(uint8_t* r struct comm_reply* repinfo, uint32_t now, struct regional* region, struct cookie_secrets* cookie_secrets) { + int i = 0, nsid_seen = 0, cookie_seen = 0, padding_seen = 0; /* To respond with a Keepalive option, the client connection must have * received one message with a TCP Keepalive EDNS option, and that * option must have 0 length data. Subsequent messages sent on that @@ -969,7 +975,7 @@ parse_edns_options_from_query(uint8_t* r /* while still more options, and have code+len to read */ /* ignores partial content (i.e. rdata len 3) */ - while(rdata_len >= 4) { + while(rdata_len >= 4 && i < MAX_PARSED_EDNS_OPTIONS) { uint16_t opt_code = sldns_read_uint16(rdata_ptr); uint16_t opt_len = sldns_read_uint16(rdata_ptr+2); uint8_t server_cookie[40]; @@ -984,8 +990,9 @@ parse_edns_options_from_query(uint8_t* r /* handle parse time edns options here */ switch(opt_code) { case LDNS_EDNS_NSID: - if (!cfg || !cfg->nsid) + if (!cfg || !cfg->nsid || nsid_seen) break; + nsid_seen = 1; if(!edns_opt_list_append(&edns->opt_list_out, LDNS_EDNS_NSID, cfg->nsid_len, cfg->nsid, region)) { @@ -1026,9 +1033,13 @@ parse_edns_options_from_query(uint8_t* r break; case LDNS_EDNS_PADDING: - if(!cfg || !cfg->pad_responses || - !c || c->type != comm_tcp ||!c->ssl) + if(!cfg || !cfg->pad_responses || !c || padding_seen) + break; + if(!((c->type == comm_tcp && c->ssl) || + (c->type == comm_http && c->ssl) || + c->type == comm_doq)) break; + padding_seen = 1; if(!edns_opt_list_append(&edns->opt_list_out, LDNS_EDNS_PADDING, 0, NULL, region)) { @@ -1039,8 +1050,9 @@ parse_edns_options_from_query(uint8_t* r break; case LDNS_EDNS_COOKIE: - if(!cfg || !cfg->do_answer_cookie || !repinfo) + if(!cfg || !cfg->do_answer_cookie || !repinfo || cookie_seen) break; + cookie_seen = 1; if(opt_len != 8 && (opt_len < 16 || opt_len > 40)) { verbose(VERB_ALGO, "worker request: " "badly formatted cookie"); @@ -1062,13 +1074,13 @@ parse_edns_options_from_query(uint8_t* r * purposes. It will be overwritten if (re)creation * is needed. */ - if(repinfo->remote_addr.ss_family == AF_INET) { + if(repinfo->client_addr.ss_family == AF_INET) { memcpy(server_cookie + 16, - &((struct sockaddr_in*)&repinfo->remote_addr)->sin_addr, 4); + &((struct sockaddr_in*)&repinfo->client_addr)->sin_addr, 4); } else { cookie_is_v4 = 0; memcpy(server_cookie + 16, - &((struct sockaddr_in6*)&repinfo->remote_addr)->sin6_addr, 16); + &((struct sockaddr_in6*)&repinfo->client_addr)->sin6_addr, 16); } if(cfg->cookie_secret_file && @@ -1080,10 +1092,10 @@ parse_edns_options_from_query(uint8_t* r cookie_is_v4, server_cookie, now); } else { /* Use the cookie option value to validate. */ - cookie_val_status = edns_cookie_server_validate( - rdata_ptr, opt_len, cfg->cookie_secret, - cfg->cookie_secret_len, cookie_is_v4, - server_cookie, now); + cookie_val_status = edns_cookie_server_validate( + rdata_ptr, opt_len, cfg->cookie_secret, + cfg->cookie_secret_len, cookie_is_v4, + server_cookie, now); } if(cookie_val_status == COOKIE_STATUS_VALID_RENEW) edns->cookie_valid = 1; @@ -1124,8 +1136,8 @@ parse_edns_options_from_query(uint8_t* r cookie_is_v4, now); lock_basic_unlock(&cookie_secrets->lock); } else { - edns_cookie_server_write(server_cookie, - cfg->cookie_secret, cookie_is_v4, now); + edns_cookie_server_write(server_cookie, + cfg->cookie_secret, cookie_is_v4, now); } if(!edns_opt_list_append(&edns->opt_list_out, LDNS_EDNS_COOKIE, 24, server_cookie, @@ -1146,6 +1158,7 @@ parse_edns_options_from_query(uint8_t* r } rdata_ptr += opt_len; rdata_len -= opt_len; + i++; } return LDNS_RCODE_NOERROR; } @@ -1160,6 +1173,7 @@ parse_extract_edns_from_response_msg(str struct rrset_parse* found_prev = 0; size_t rdata_len; uint8_t* rdata_ptr; + int i = 0; /* since the class encodes the UDP size, we cannot use hash table to * find the EDNS OPT record. Scan the packet. */ while(rrset) { @@ -1219,7 +1233,7 @@ parse_extract_edns_from_response_msg(str /* while still more options, and have code+len to read */ /* ignores partial content (i.e. rdata len 3) */ - while(rdata_len >= 4) { + while(rdata_len >= 4 && i < MAX_PARSED_EDNS_OPTIONS) { uint16_t opt_code = sldns_read_uint16(rdata_ptr); uint16_t opt_len = sldns_read_uint16(rdata_ptr+2); rdata_ptr += 4; @@ -1234,6 +1248,7 @@ parse_extract_edns_from_response_msg(str } rdata_ptr += opt_len; rdata_len -= opt_len; + i++; } /* ignore rrsigs */ return LDNS_RCODE_NOERROR; @@ -1361,3 +1376,15 @@ msgparse_rrset_remove_rr(const char* str * the rr->next works fine to continue. */ return rrset->rr_count == 0; } + +#ifdef UNBOUND_DEBUG +time_t debug_expired_reply_ttl_calc(time_t ttl, time_t ttl_add) { + /* Check that we are serving expired when this is called */ + /* ttl (absolute) should be later than ttl_add */ + /* It is also called during the grace period for type DNAME, + * and then the 'SERVE_EXPIRED' boolean may not be on. */ + log_assert(ttl_add <= ttl); + return (SERVE_EXPIRED_REPLY_TTL < (ttl) - (ttl_add) ? + SERVE_EXPIRED_REPLY_TTL : (ttl) - (ttl_add)); +} +#endif Index: sbin/unwind/libunbound/util/data/msgparse.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/data/msgparse.h,v diff -u -p -r1.11 msgparse.h --- sbin/unwind/libunbound/util/data/msgparse.h 29 Sep 2025 14:53:38 -0000 1.11 +++ sbin/unwind/libunbound/util/data/msgparse.h 21 Sep 2026 16:28:29 -0000 @@ -98,6 +98,31 @@ extern time_t SERVE_EXPIRED_REPLY_TTL; /** If we serve the original TTL or decrementing TTLs */ extern int SERVE_ORIGINAL_TTL; +/** calculate the prefetch TTL as 90% of original. Calculation + * without numerical overflow (uin32_t) */ +#define PREFETCH_TTL_CALC(ttl) ((ttl) - (ttl)/10) + +/* caclulate the TTL used for expired answers to somewhat make sense wrt the + * original TTL; don't reply with higher TTL than the original */ +#ifdef UNBOUND_DEBUG +time_t debug_expired_reply_ttl_calc(time_t ttl, time_t ttl_add); +#define EXPIRED_REPLY_TTL_CALC(ttl, ttl_add) \ + debug_expired_reply_ttl_calc(ttl, ttl_add) +#else +#define EXPIRED_REPLY_TTL_CALC(ttl, ttl_add) \ + (SERVE_EXPIRED_REPLY_TTL < (ttl) - (ttl_add) ? \ + SERVE_EXPIRED_REPLY_TTL : (ttl) - (ttl_add)) +#endif + +/** Update the reply_info TTL from an RRSet's TTL, essentially keeping the TTL + * sane with all the (progressively added) rrsets to the message */ +#define UPDATE_TTL_FROM_RRSET(ttl, rrsetttl) \ + ((ttl) = ((ttl) < (rrsetttl)) ? (ttl) : (rrsetttl)) + +/** Check if TTL is expired. 0 TTL is considered expired. + * Used mainly to identify parts of the code that do this comparison. */ +#define TTL_IS_EXPIRED(ttl, now) ((ttl) <= (now)) + /** * Data stored in scratch pad memory during parsing. * Stores the data that will enter into the msgreply and packet result. Index: sbin/unwind/libunbound/util/data/msgreply.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/data/msgreply.c,v diff -u -p -r1.16 msgreply.c --- sbin/unwind/libunbound/util/data/msgreply.c 29 Sep 2025 14:53:38 -0000 1.16 +++ sbin/unwind/libunbound/util/data/msgreply.c 21 Sep 2026 16:28:29 -0000 @@ -178,9 +178,9 @@ reply_info_alloc_rrset_keys(struct reply int reply_info_can_answer_expired(struct reply_info* rep, time_t timenow) { - log_assert(rep->ttl < timenow); + log_assert(TTL_IS_EXPIRED(rep->ttl, timenow)); /* Really expired */ - if(SERVE_EXPIRED_TTL && rep->serve_expired_ttl < timenow) return 0; + if(SERVE_EXPIRED_TTL && TTL_IS_EXPIRED(rep->serve_expired_ttl, timenow)) return 0; /* Ignore expired failure answers */ if(FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NOERROR && FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NXDOMAIN && @@ -188,12 +188,13 @@ reply_info_can_answer_expired(struct rep return 1; } -int reply_info_could_use_expired(struct reply_info* rep, time_t timenow) +int +reply_info_could_use_expired(struct reply_info* rep, time_t timenow) { - log_assert(rep->ttl < timenow); + log_assert(TTL_IS_EXPIRED(rep->ttl, timenow)); /* Really expired */ - if(SERVE_EXPIRED_TTL && rep->serve_expired_ttl < timenow && - !SERVE_EXPIRED_TTL_RESET) return 0; + if(SERVE_EXPIRED_TTL && TTL_IS_EXPIRED(rep->serve_expired_ttl, timenow) + && !SERVE_EXPIRED_TTL_RESET) return 0; /* Ignore expired failure answers */ if(FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NOERROR && FLAGS_GET_RCODE(rep->flags) != LDNS_RCODE_NXDOMAIN && @@ -229,7 +230,7 @@ make_new_reply_info(const struct reply_i } /** find the minimumttl in the rdata of SOA record */ -static time_t +static uint32_t soa_find_minttl(struct rr_parse* rr) { uint16_t rlen = sldns_read_uint16(rr->ttl_data+4); @@ -237,7 +238,7 @@ soa_find_minttl(struct rr_parse* rr) return 0; /* rdata too small for SOA (dname, dname, 5*32bit) */ /* minimum TTL is the last 32bit value in the rdata of the record */ /* at position ttl_data + 4(ttl) + 2(rdatalen) + rdatalen - 4(timeval)*/ - return (time_t)sldns_read_uint32(rr->ttl_data+6+rlen-4); + return sldns_read_uint32(rr->ttl_data+6+rlen-4); } /** do the rdata copy */ @@ -247,37 +248,41 @@ rdata_copy(sldns_buffer* pkt, struct pac sldns_pkt_section section) { uint16_t pkt_len; + size_t tolen; + uint32_t ttl; const sldns_rr_descriptor* desc; - *rr_ttl = sldns_read_uint32(rr->ttl_data); + ttl = sldns_read_uint32(rr->ttl_data); /* RFC 2181 Section 8. if msb of ttl is set treat as if zero. */ - if((*rr_ttl & 0x80000000U)) - *rr_ttl = 0; + /* RFC 8767 Section 4. values with high-order bit as positive, not 0. ++ * As such, it will be capped by MAX_TTL below. */ if(type == LDNS_RR_TYPE_SOA && section == LDNS_SECTION_AUTHORITY) { /* negative response. see if TTL of SOA record larger than the * minimum-ttl in the rdata of the SOA record */ - if(*rr_ttl > soa_find_minttl(rr)) *rr_ttl = soa_find_minttl(rr); + if(ttl > soa_find_minttl(rr)) ttl = soa_find_minttl(rr); if(!SERVE_ORIGINAL_TTL) { /* If MIN_NEG_TTL is configured skip setting MIN_TTL */ - if(MIN_NEG_TTL <= 0 && *rr_ttl < MIN_TTL) { - *rr_ttl = MIN_TTL; + if(MIN_NEG_TTL <= 0 && ttl < (uint32_t)MIN_TTL) { + ttl = (uint32_t)MIN_TTL; } - if(*rr_ttl > MAX_TTL) *rr_ttl = MAX_TTL; + if(ttl > (uint32_t)MAX_TTL) ttl = (uint32_t)MAX_TTL; } /* MAX_NEG_TTL overrides the min and max ttl of everything * else; it is for a more specific record */ - if(*rr_ttl > MAX_NEG_TTL) *rr_ttl = MAX_NEG_TTL; + if(ttl > (uint32_t)MAX_NEG_TTL) ttl = (uint32_t)MAX_NEG_TTL; /* MIN_NEG_TTL overrides the min and max ttl of everything * else if configured; it is for a more specific record */ - if(MIN_NEG_TTL > 0 && *rr_ttl < MIN_NEG_TTL) { - *rr_ttl = MIN_NEG_TTL; + if(MIN_NEG_TTL > 0 && ttl < (uint32_t)MIN_NEG_TTL) { + ttl = (uint32_t)MIN_NEG_TTL; } } else if(!SERVE_ORIGINAL_TTL) { - if(*rr_ttl < MIN_TTL) *rr_ttl = MIN_TTL; - if(*rr_ttl > MAX_TTL) *rr_ttl = MAX_TTL; + if(ttl < (uint32_t)MIN_TTL) ttl = (uint32_t)MIN_TTL; + if(ttl > (uint32_t)MAX_TTL) ttl = (uint32_t)MAX_TTL; } - if(*rr_ttl < data->ttl) - data->ttl = *rr_ttl; + if((time_t)ttl < data->ttl) + data->ttl = (time_t)ttl; + /* We have concluded the TTL checks */ + *rr_ttl = (time_t)ttl; if(rr->outside_packet) { /* uncompressed already, only needs copy */ @@ -289,9 +294,13 @@ rdata_copy(sldns_buffer* pkt, struct pac (rr->ttl_data - sldns_buffer_begin(pkt) + sizeof(uint32_t))); /* insert decompressed size into rdata len stored in memory */ /* -2 because rdatalen bytes are not included. */ + tolen = rr->size; + if(tolen < 2) + return 0; pkt_len = htons(rr->size - 2); memmove(to, &pkt_len, sizeof(uint16_t)); to += 2; + tolen -= 2; /* read packet rdata len */ pkt_len = sldns_buffer_read_u16(pkt); if(sldns_buffer_remaining(pkt) < pkt_len) @@ -300,16 +309,29 @@ rdata_copy(sldns_buffer* pkt, struct pac if(pkt_len > 0 && desc && desc->_dname_count > 0) { int count = (int)desc->_dname_count; int rdf = 0; - size_t len; - size_t oldpos; + size_t len, dlen; + size_t oldpos, newpos; /* decompress dnames. */ while(pkt_len > 0 && count) { switch(desc->_wireformat[rdf]) { case LDNS_RDF_TYPE_DNAME: oldpos = sldns_buffer_position(pkt); - dname_pkt_copy(pkt, to, + dlen = pkt_dname_len(pkt); + if(dlen == 0) + return 0; /* malformed */ + if(dlen > tolen) + return 0; /* alloc mismatch */ + newpos = sldns_buffer_position(pkt); + if(oldpos > newpos) + return 0; /* should have moved forward*/ + sldns_buffer_set_position(pkt, oldpos); + dname_pkt_copy(pkt, to, sldns_buffer_current(pkt)); - to += pkt_dname_len(pkt); + sldns_buffer_set_position(pkt, newpos); + to += dlen; + tolen -= dlen; + if(sldns_buffer_position(pkt)-oldpos > pkt_len) + return 0; /* malformed: walks diverged */ pkt_len -= sldns_buffer_position(pkt)-oldpos; count--; len = 0; @@ -322,9 +344,12 @@ rdata_copy(sldns_buffer* pkt, struct pac break; } if(len) { + if(len > tolen) + return 0; /* alloc mismatch */ log_assert(len <= pkt_len); memmove(to, sldns_buffer_current(pkt), len); to += len; + tolen -= len; sldns_buffer_skip(pkt, (ssize_t)len); pkt_len -= len; } @@ -332,8 +357,11 @@ rdata_copy(sldns_buffer* pkt, struct pac } } /* copy remaining rdata */ - if(pkt_len > 0) + if(pkt_len > 0) { + if(pkt_len > tolen) + return 0; /* alloc mismatch */ memmove(to, sldns_buffer_current(pkt), pkt_len); + } return 1; } @@ -479,7 +507,11 @@ parse_copy_decompress_rrset(sldns_buffer } pk->entry.data = (void*)data; pk->entry.key = (void*)pk; - pk->entry.hash = pset->hash; + pk->rk.flags |= (data->ttl == 0) ? PACKED_RRSET_UPSTREAM_0TTL : 0; + if( (pk->rk.flags & PACKED_RRSET_UPSTREAM_0TTL) != 0) + pk->entry.hash = rrset_key_hash(&pk->rk); + else + pk->entry.hash = pset->hash; data->trust = get_rrset_trust(msg, pset); return 1; } @@ -617,6 +649,29 @@ reply_info_set_ttls(struct reply_info* r } } +void +reply_info_absolute_ttls(struct reply_info* rep, time_t ttl, time_t ttl_add) +{ + size_t i, j; + rep->ttl = ttl; + rep->prefetch_ttl = PREFETCH_TTL_CALC(ttl); + rep->serve_expired_ttl = ttl + SERVE_EXPIRED_TTL; + /* Don't set rep->serve_expired_norec_ttl; this should only be set + * on cached records when encountering an error */ + log_assert(rep->serve_expired_norec_ttl == 0); + for(i=0; irrset_count; i++) { + struct packed_rrset_data* data = (struct packed_rrset_data*) + rep->ref[i].key->entry.data; + if(i>0 && rep->ref[i].key == rep->ref[i-1].key) + continue; + data->ttl = ttl; + for(j=0; jcount + data->rrsig_count; j++) { + data->rr_ttl[j] = ttl; + } + data->ttl_add = ttl_add; + } +} + void reply_info_parsedelete(struct reply_info* rep, struct alloc_cache* alloc) { @@ -1084,6 +1139,17 @@ reply_all_rrsets_secure(struct reply_inf return 1; } +int reply_an_ns_rrsets_secure(struct reply_info* rep) +{ + size_t i; + for(i=0; ian_numrrsets+rep->ns_numrrsets; i++) { + if( ((struct packed_rrset_data*)rep->rrsets[i]->entry.data) + ->security != sec_status_secure ) + return 0; + } + return 1; +} + struct reply_info* parse_reply_in_temp_region(sldns_buffer* pkt, struct regional* region, struct query_info* qi) @@ -1475,8 +1541,12 @@ struct edns_option* edns_opt_list_find(s int local_alias_shallow_copy_qname(struct local_rrset* local_alias, uint8_t** qname, size_t* qname_len) { - struct ub_packed_rrset_key* rrset = local_alias->rrset; - struct packed_rrset_data* d = rrset->entry.data; + struct ub_packed_rrset_key* rrset; + struct packed_rrset_data* d; + rrset = local_alias->rrset; + if(!rrset) return 0; + d = rrset->entry.data; + if(!d) return 0; /* Sanity check: our current implementation only supports * a single CNAME RRset as a local alias. */ Index: sbin/unwind/libunbound/util/data/msgreply.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/data/msgreply.h,v diff -u -p -r1.11 msgreply.h --- sbin/unwind/libunbound/util/data/msgreply.h 29 Sep 2025 14:53:38 -0000 1.11 +++ sbin/unwind/libunbound/util/data/msgreply.h 21 Sep 2026 16:28:29 -0000 @@ -44,6 +44,10 @@ #include "util/storage/lruhash.h" #include "util/data/packed_rrset.h" #include "sldns/rrdef.h" +#ifdef __QNX__ +/* For struct timeval */ +#include +#endif /* __QNX__ */ struct sldns_buffer; struct comm_reply; struct alloc_cache; @@ -60,10 +64,6 @@ struct local_rrset; struct dns_msg; enum comm_point_type; -/** calculate the prefetch TTL as 90% of original. Calculation - * without numerical overflow (uin32_t) */ -#define PREFETCH_TTL_CALC(ttl) ((ttl) - (ttl)/10) - /** * Structure to store query information that makes answers to queries * different. @@ -340,6 +340,15 @@ void reply_info_sortref(struct reply_inf */ void reply_info_set_ttls(struct reply_info* rep, time_t timenow); +/** + * Set TTLs inside the replyinfo to the given absolute values. + * @param rep: reply info. rrsets must be filled in. + * Also refs must be filled in. + * @param ttl: absolute ttl value to be set. + * @param ttl_add: the current time to be used verbatim for ttl_add in the rrsets. + */ +void reply_info_absolute_ttls(struct reply_info* rep, time_t ttl, time_t ttl_add); + /** * Delete reply_info and packed_rrsets (while they are not yet added to the * hashtables.). Returns rrsets to the alloc cache. @@ -485,6 +494,9 @@ int reply_check_cname_chain(struct query */ int reply_all_rrsets_secure(struct reply_info* rep); +/** Check status of answer and authority section RRs. */ +int reply_an_ns_rrsets_secure(struct reply_info* rep); + /** * Find answer rrset in reply, the one matching qinfo. Follows CNAMEs, so the * result may have a different owner name. @@ -572,7 +584,7 @@ void log_query_info(enum verbosity_value struct query_info* qinf); /** - * Append edns option to edns option list + * Append edns option to edns option list. * @param list: the edns option list to append the edns option to. * @param code: the edns option's code. * @param len: the edns option's length. @@ -584,17 +596,20 @@ int edns_opt_list_append(struct edns_opt uint8_t* data, struct regional* region); /** - * Append edns EDE option to edns options list + * Append edns EDE option to edns options list. + * We need ATTR_NONSTRING because we are trimming the trailing \0 of static + * string (TXT) when assigning to ede.text; it silences compiler nonstring + * warnings. * @param LIST: the edns option list to append the edns option to. * @param REGION: region to allocate the new edns option. * @param CODE: the EDE code. - * @param TXT: Additional text for the option + * @param TXT: Additional text for the option. */ #define EDNS_OPT_LIST_APPEND_EDE(LIST, REGION, CODE, TXT) \ do { \ struct { \ uint16_t code; \ - char text[sizeof(TXT) - 1]; \ + char ATTR_NONSTRING(text[sizeof(TXT) - 1]) ; \ } ede = { htons(CODE), TXT }; \ verbose(VERB_ALGO, "attached EDE code: %d with" \ " message: '%s'", CODE, TXT); \ Index: sbin/unwind/libunbound/util/data/packed_rrset.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/data/packed_rrset.c,v diff -u -p -r1.4 packed_rrset.c --- sbin/unwind/libunbound/util/data/packed_rrset.c 13 Apr 2024 13:58:35 -0000 1.4 +++ sbin/unwind/libunbound/util/data/packed_rrset.c 21 Sep 2026 16:28:29 -0000 @@ -198,6 +198,7 @@ get_cname_target(struct ub_packed_rrset_ { struct packed_rrset_data* d; size_t len; + if(!rrset) return; if(ntohs(rrset->rk.type) != LDNS_RR_TYPE_CNAME && ntohs(rrset->rk.type) != LDNS_RR_TYPE_DNAME) return; @@ -296,7 +297,7 @@ int packed_rr_to_string(struct ub_packed wlen = (size_t)sldns_wire2str_rr_buf(rr, rlen, dest, dest_len); if(wlen >= dest_len) { /* the output string was truncated */ - log_info("rrbuf failure %d %s", (int)d->rr_len[i], dest); + verbose(VERB_ALGO, "rrbuf failure %d %s", (int)d->rr_len[i], dest); dest[0] = 0; return 0; } @@ -336,10 +337,9 @@ packed_rrset_copy_region(struct ub_packe struct ub_packed_rrset_key* ck = regional_alloc(region, sizeof(struct ub_packed_rrset_key)); struct packed_rrset_data* d; - struct packed_rrset_data* data = (struct packed_rrset_data*) - key->entry.data; + struct packed_rrset_data* data = key->entry.data; size_t dsize, i; - time_t adjust = 0; + time_t now_control; if(!ck) return NULL; ck->id = key->id; @@ -352,22 +352,34 @@ packed_rrset_copy_region(struct ub_packe if(!ck->rk.dname) return NULL; dsize = packed_rrset_sizeof(data); - d = (struct packed_rrset_data*)regional_alloc_init(region, data, dsize); + d = regional_alloc_init(region, data, dsize); if(!d) return NULL; ck->entry.data = d; packed_rrset_ptr_fixup(d); - /* make TTLs relative - once per rrset */ - adjust = SERVE_ORIGINAL_TTL ? data->ttl_add : now; - for(i=0; icount + d->rrsig_count; i++) { - if(d->rr_ttl[i] < adjust) - d->rr_ttl[i] = SERVE_EXPIRED?SERVE_EXPIRED_REPLY_TTL:0; - else d->rr_ttl[i] -= adjust; + /* make TTLs relative - once per rr */ + if(now > 0) { + /* NS RRSets may be here with ttl_add higher than now because + * of the novel ghost attack mitigation i.e., using the + * qstarttime for NS RRSets. In that case make sure that the + * returned TTL is not higher than the original one. */ + /* For types other than type NS, auth zone and rpz code + * can have ttl_add values. Also time could conceivably move + * in reverse, due to operator action, and it is prudent + * to not assert on that here. + * So there is no assertion d->ttl_add <= now || type==NS */ + now_control = SERVE_ORIGINAL_TTL ? data->ttl_add + : (d->ttl_add > now ? d->ttl_add : now ); + for(i=0; icount + d->rrsig_count; i++) { + if(TTL_IS_EXPIRED(d->rr_ttl[i], now_control)) { + d->rr_ttl[i] = EXPIRED_REPLY_TTL_CALC(d->rr_ttl[i], data->ttl_add); + } else d->rr_ttl[i] -= now_control; + } + if(TTL_IS_EXPIRED(d->ttl, now_control)) { + d->ttl = EXPIRED_REPLY_TTL_CALC(d->ttl, data->ttl_add); + } else d->ttl -= now_control; + d->ttl_add = 0; /* TTLs have been made relative */ } - if(d->ttl < adjust) - d->ttl = SERVE_EXPIRED?SERVE_EXPIRED_REPLY_TTL:0; - else d->ttl -= adjust; - d->ttl_add = 0; /* TTLs have been made relative */ return ck; } Index: sbin/unwind/libunbound/util/data/packed_rrset.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/data/packed_rrset.h,v diff -u -p -r1.5 packed_rrset.h --- sbin/unwind/libunbound/util/data/packed_rrset.h 23 Feb 2025 07:53:40 -0000 1.5 +++ sbin/unwind/libunbound/util/data/packed_rrset.h 21 Sep 2026 16:28:29 -0000 @@ -70,6 +70,10 @@ typedef uint64_t rrset_id_type; #define PACKED_RRSET_RPZ 0x8 /** this rrset is A/AAAA and is an unverified glue record */ #define PACKED_RRSET_UNVERIFIED_GLUE 0x10 +/** this rrset has a 0TTL from upstream */ +#define PACKED_RRSET_UPSTREAM_0TTL 0x20 +/** this rrset has 0TTL from upstream and also has had grace TTL applied */ +#define PACKED_RRSET_0TTL_GRACE 0x40 /** number of rrs and rrsets for integer overflow protection. More than * this is not really possible (64K packet has much less RRs and RRsets) in @@ -99,6 +103,7 @@ struct packed_rrset_key { * o PACKED_RRSET_FIXEDTTL (not supposed to be cached) * o PACKED_RRSET_RPZ * o PACKED_RRSET_UNVERIFIED_GLUE + * o PACKED_RRSET_UPSTREAM_0TTL (not supposed to be cached) */ uint32_t flags; /** the rrset type in network format */ Index: sbin/unwind/libunbound/util/storage/lookup3.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/util/storage/lookup3.c,v diff -u -p -r1.5 lookup3.c --- sbin/unwind/libunbound/util/storage/lookup3.c 5 Sep 2024 08:22:48 -0000 1.5 +++ sbin/unwind/libunbound/util/storage/lookup3.c 21 Sep 2026 16:28:29 -0000 @@ -255,10 +255,10 @@ uint32_t initval) /* the { case 3 : c+=k[2]; ATTR_FALLTHROUGH - /* fallthrough */ + /* fallthrough */ case 2 : b+=k[1]; ATTR_FALLTHROUGH - /* fallthrough */ + /* fallthrough */ case 1 : a+=k[0]; final(a,b,c); ATTR_FALLTHROUGH @@ -531,37 +531,37 @@ uint32_t hashlittle( const void *key, si { case 12: c+=((uint32_t)k[11])<<24; ATTR_FALLTHROUGH - /* fallthrough */ + /* fallthrough */ case 11: c+=((uint32_t)k[10])<<16; ATTR_FALLTHROUGH - /* fallthrough */ + /* fallthrough */ case 10: c+=((uint32_t)k[9])<<8; ATTR_FALLTHROUGH - /* fallthrough */ + /* fallthrough */ case 9 : c+=k[8]; ATTR_FALLTHROUGH - /* fallthrough */ + /* fallthrough */ case 8 : b+=((uint32_t)k[7])<<24; ATTR_FALLTHROUGH - /* fallthrough */ + /* fallthrough */ case 7 : b+=((uint32_t)k[6])<<16; ATTR_FALLTHROUGH - /* fallthrough */ + /* fallthrough */ case 6 : b+=((uint32_t)k[5])<<8; ATTR_FALLTHROUGH - /* fallthrough */ + /* fallthrough */ case 5 : b+=k[4]; ATTR_FALLTHROUGH - /* fallthrough */ + /* fallthrough */ case 4 : a+=((uint32_t)k[3])<<24; ATTR_FALLTHROUGH - /* fallthrough */ + /* fallthrough */ case 3 : a+=((uint32_t)k[2])<<16; ATTR_FALLTHROUGH - /* fallthrough */ + /* fallthrough */ case 2 : a+=((uint32_t)k[1])<<8; ATTR_FALLTHROUGH - /* fallthrough */ + /* fallthrough */ case 1 : a+=k[0]; break; case 0 : return c; Index: sbin/unwind/libunbound/validator/autotrust.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/validator/autotrust.c,v diff -u -p -r1.12 autotrust.c --- sbin/unwind/libunbound/validator/autotrust.c 14 Sep 2025 15:16:53 -0000 1.12 +++ sbin/unwind/libunbound/validator/autotrust.c 21 Sep 2026 16:28:29 -0000 @@ -160,10 +160,12 @@ verbose_key(struct autr_ta* ta, enum ver * Parse comments * @param str: to parse * @param ta: trust key autotrust metadata + * @param header_seen: if an autotrust file header was seen. + * Without such a header it is a list of resource records. * @return false on failure. */ static int -parse_comments(char* str, struct autr_ta* ta) +parse_comments(char* str, struct autr_ta* ta, int header_seen) { int len = (int)strlen(str), pos = 0, timestamp = 0; char* comment = (char*) malloc(sizeof(char)*len+1); @@ -196,10 +198,18 @@ parse_comments(char* str, struct autr_ta free(comment); return 0; } - if (pos <= 0) - ta->s = AUTR_STATE_VALID; - else - { + if (pos <= 0) { + if(header_seen) { + /* There was an autotrust trust anchor file header, + * with a ;; id=.. line, so the entries + * have to have ;;state= annotations. */ + log_err("trust anchor in state file has no ;;state= " + "annotation, ignoring"); + free(comment); + return 0; + } + ta->s = AUTR_STATE_VALID; + } else { int s = (int) comments[pos] - '0'; switch(s) { @@ -391,6 +401,15 @@ autr_rrset_delete(struct ub_packed_rrset } } +/** delete autotrust key data */ +static void +autr_ta_delete(struct autr_ta* ta) +{ + if(!ta) return; + free(ta->rr); + free(ta); +} + void autr_point_delete(struct trust_anchor* tp) { if(!tp) @@ -404,8 +423,7 @@ void autr_point_delete(struct trust_anch struct autr_ta* p = tp->autr->keys, *np; while(p) { np = p->next; - free(p->rr); - free(p); + autr_ta_delete(p); p = np; } free(tp->autr->file); @@ -449,8 +467,7 @@ add_trustanchor_frm_rr(struct val_anchor return NULL; *tp = find_add_tp(anchors, rr, rr_len, dname_len); if(!*tp) { - free(ta->rr); - free(ta); + autr_ta_delete(ta); return NULL; } /* add ta to tp */ @@ -523,12 +540,14 @@ add_trustanchor_frm_str(struct val_ancho * @param prev: passed to ldns. * @param prev_len: length of prev * @param skip: if true, the result is NULL, but not an error, skip it. + * @param header_seen: if an autotrust file header was seen. + * Without such a header it is a list of resource records. * @return false on failure, otherwise the tp read. */ static struct trust_anchor* load_trustanchor(struct val_anchors* anchors, char* str, const char* fname, uint8_t* origin, size_t origin_len, uint8_t** prev, size_t* prev_len, - int* skip) + int* skip, int header_seen) { struct autr_ta* ta = NULL; struct trust_anchor* tp = NULL; @@ -538,7 +557,11 @@ load_trustanchor(struct val_anchors* anc if(!ta) return NULL; lock_basic_lock(&tp->lock); - if(!parse_comments(str, ta)) { + if(!parse_comments(str, ta, header_seen)) { + /* ta was already linked into the list of keys, unlink it */ + log_assert(tp->autr->keys == ta); + tp->autr->keys = ta->next; + autr_ta_delete(ta); lock_basic_unlock(&tp->lock); return NULL; } @@ -846,19 +869,32 @@ parse_id(struct val_anchors* anchors, ch * @param anchors: the anchor is added to this, if "id:" is seen. * @param anchor: the anchor as result value or previously returned anchor * value to read the variable lines into. + * @param header_seen: if a header ';;id: example.com.' was seen. + * @param nm: file name. * @return: 0 no match, -1 failed syntax error, +1 success line read. * +2 revoked trust anchor file. */ static int parse_var_line(char* line, struct val_anchors* anchors, - struct trust_anchor** anchor) + struct trust_anchor** anchor, int* header_seen, const char* nm) { struct trust_anchor* tp = *anchor; int r = 0; if(strncmp(line, ";;id: ", 6) == 0) { + *header_seen = 1; *anchor = parse_id(anchors, line+6); if(!*anchor) return -1; - else return 1; + lock_basic_lock(&(*anchor)->lock); + if(*anchor && !(*anchor)->autr->file) { + (*anchor)->autr->file = strdup(nm); + if(!(*anchor)->autr->file) { + lock_basic_unlock(&(*anchor)->lock); + log_err("malloc failure"); + return -1; + } + } + lock_basic_unlock(&(*anchor)->lock); + if(*anchor) return 1; } else if(strncmp(line, ";;REVOKED", 9) == 0) { if(tp) { log_err("REVOKED statement must be at start of file"); @@ -992,14 +1028,15 @@ int autr_read_file(struct val_anchors* a FILE* fd; /* keep track of line numbers */ int line_nr = 0; - /* single line */ - char line[10240]; + /* single line, enough space for large DNSKEY, 64K, in hex and dname */ + char line[10240+65536*2]; /* trust point being read */ struct trust_anchor *tp = NULL, *tp2; int r; /* for $ORIGIN parsing */ uint8_t *origin=NULL, *prev=NULL; size_t origin_len=0, prev_len=0; + int header_seen = 0; if (!(fd = fopen(nm, "r"))) { log_err("unable to open %s for reading: %s", @@ -1008,7 +1045,7 @@ int autr_read_file(struct val_anchors* a } verbose(VERB_ALGO, "reading autotrust anchor file %s", nm); while ( (r=read_multiline(line, sizeof(line), fd, &line_nr)) != 0) { - if(r == -1 || (r = parse_var_line(line, anchors, &tp)) == -1) { + if(r == -1 || (r = parse_var_line(line, anchors, &tp, &header_seen, nm)) == -1) { log_err("could not parse auto-trust-anchor-file " "%s line %d", nm, line_nr); fclose(fd); @@ -1030,7 +1067,7 @@ int autr_read_file(struct val_anchors* a continue; r = 0; if(!(tp2=load_trustanchor(anchors, line, nm, origin, - origin_len, &prev, &prev_len, &r))) { + origin_len, &prev, &prev_len, &r, header_seen))) { if(!r) log_err("failed to load trust anchor from %s " "at line %i, skipping", nm, line_nr); /* try to do the rest */ @@ -1198,6 +1235,11 @@ void autr_write_file(struct module_env* #endif char tempf[2048]; log_assert(tp->autr); + if(!fname) { + log_err("autotrust: trust point has no backing file, " + "skipping write"); + return; + } if(!env) { log_err("autr_write_file: Module environment is NULL."); return; @@ -1259,12 +1301,13 @@ void autr_write_file(struct module_env* * @param tp: trust point to verify with * @param rrset: DNSKEY rrset to verify. * @param qstate: qstate with region. + * @param vq: validator query state. * @return false on failure, true if verification successful. */ static int verify_dnskey(struct module_env* env, struct val_env* ve, struct trust_anchor* tp, struct ub_packed_rrset_key* rrset, - struct module_qstate* qstate) + struct module_qstate* qstate, struct val_qstate* vq) { char reasonbuf[256]; char* reason = NULL; @@ -1272,7 +1315,7 @@ verify_dnskey(struct module_env* env, st int downprot = env->cfg->harden_algo_downgrade; enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve, rrset, tp->ds_rrset, tp->dnskey_rrset, downprot?sigalg:NULL, &reason, - NULL, qstate, reasonbuf, sizeof(reasonbuf)); + NULL, qstate, vq, reasonbuf, sizeof(reasonbuf)); /* sigalg is ignored, it returns algorithms signalled to exist, but * in 5011 there are no other rrsets to check. if downprot is * enabled, then it checks that the DNSKEY is signed with all @@ -1312,16 +1355,18 @@ min_expiry(struct module_env* env, struc static int rr_is_selfsigned_revoked(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset, size_t i, - struct module_qstate* qstate) + struct module_qstate* qstate, struct val_qstate* vq) { enum sec_status sec; char* reason = NULL; + size_t num_tagmatches = 0; verbose(VERB_ALGO, "seen REVOKE flag, check self-signed, rr %d", (int)i); /* no algorithm downgrade protection necessary, if it is selfsigned * revoked it can be removed. */ sec = dnskey_verify_rrset(env, ve, dnskey_rrset, dnskey_rrset, i, - &reason, NULL, LDNS_SECTION_ANSWER, qstate); + &reason, NULL, LDNS_SECTION_ANSWER, qstate, vq, + &num_tagmatches); return (sec == sec_status_secure); } @@ -1537,7 +1582,7 @@ init_events(struct trust_anchor* tp) static void check_contains_revoked(struct module_env* env, struct val_env* ve, struct trust_anchor* tp, struct ub_packed_rrset_key* dnskey_rrset, - int* changed, struct module_qstate* qstate) + int* changed, struct module_qstate* qstate, struct val_qstate* vq) { struct packed_rrset_data* dd = (struct packed_rrset_data*) dnskey_rrset->entry.data; @@ -1557,7 +1602,8 @@ check_contains_revoked(struct module_env } if(!ta) continue; /* key not found */ - if(rr_is_selfsigned_revoked(env, ve, dnskey_rrset, i, qstate)) { + if(rr_is_selfsigned_revoked(env, ve, dnskey_rrset, i, qstate, + vq)) { /* checked if there is an rrsig signed by this key. */ /* same keytag, but stored can be revoked already, so * compare keytags, with +0 or +128(REVOKE flag) */ @@ -1996,8 +2042,7 @@ autr_cleanup_keys(struct trust_anchor* t != LDNS_RR_TYPE_DNSKEY) { struct autr_ta* np = p->next; /* remove */ - free(p->rr); - free(p); + autr_ta_delete(p); /* snip and go to next item */ *prevp = np; p = np; @@ -2172,7 +2217,7 @@ autr_tp_remove(struct module_env* env, s int autr_process_prime(struct module_env* env, struct val_env* ve, struct trust_anchor* tp, struct ub_packed_rrset_key* dnskey_rrset, - struct module_qstate* qstate) + struct module_qstate* qstate, struct val_qstate* vq) { int changed = 0; log_assert(tp && tp->autr); @@ -2213,7 +2258,7 @@ int autr_process_prime(struct module_env return 1; /* trust point exists */ } /* check for revoked keys to remove immediately */ - check_contains_revoked(env, ve, tp, dnskey_rrset, &changed, qstate); + check_contains_revoked(env, ve, tp, dnskey_rrset, &changed, qstate, vq); if(changed) { verbose(VERB_ALGO, "autotrust: revokedkeys, reassemble"); if(!autr_assemble(tp)) { @@ -2229,7 +2274,7 @@ int autr_process_prime(struct module_env } } /* verify the dnskey rrset and see if it is valid. */ - if(!verify_dnskey(env, ve, tp, dnskey_rrset, qstate)) { + if(!verify_dnskey(env, ve, tp, dnskey_rrset, qstate, vq)) { verbose(VERB_ALGO, "autotrust: dnskey did not verify."); /* only increase failure count if this is not the first prime, * this means there was a previous successful probe */ @@ -2322,7 +2367,7 @@ autr_debug_print_tp(struct trust_anchor* if(tp->dnskey_rrset) { log_packed_rrset(NO_VERBOSE, "DNSKEY:", tp->dnskey_rrset); } - log_info("file %s", tp->autr->file); + log_info("file %s", (tp->autr->file?tp->autr->file:"null")); (void)autr_ctime_r(&tp->autr->last_queried, buf); if(buf[0]) buf[strlen(buf)-1]=0; /* remove newline */ log_info("last_queried: %u %s", (unsigned)tp->autr->last_queried, buf); @@ -2420,7 +2465,7 @@ probe_anchor(struct module_env* env, str qinfo.qclass); if(!mesh_new_callback(env->mesh, &qinfo, qflags, &edns, buf, 0, - &probe_answer_cb, env, 0)) { + &probe_answer_cb, env, 0, NULL)) { log_err("out of memory making 5011 probe"); } } Index: sbin/unwind/libunbound/validator/autotrust.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/validator/autotrust.h,v diff -u -p -r1.1 autotrust.h --- sbin/unwind/libunbound/validator/autotrust.h 23 Jan 2019 13:05:27 -0000 1.1 +++ sbin/unwind/libunbound/validator/autotrust.h 21 Sep 2026 16:28:29 -0000 @@ -50,6 +50,7 @@ struct module_env; struct module_qstate; struct val_env; struct sldns_buffer; +struct val_qstate; /** Autotrust anchor states */ typedef enum { @@ -190,13 +191,14 @@ void autr_point_delete(struct trust_anch * @param dnskey_rrset: DNSKEY rrset probed (can be NULL if bad prime result). * allocated in a region. Has not been validated yet. * @param qstate: qstate with region. + * @param vq: validator query state. * @return false if trust anchor was revoked completely. * Otherwise logs errors to log, does not change return value. * On errors, likely the trust point has been unchanged. */ int autr_process_prime(struct module_env* env, struct val_env* ve, struct trust_anchor* tp, struct ub_packed_rrset_key* dnskey_rrset, - struct module_qstate* qstate); + struct module_qstate* qstate, struct val_qstate* vq); /** * Debug printout of rfc5011 tracked anchors Index: sbin/unwind/libunbound/validator/val_anchor.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/validator/val_anchor.c,v diff -u -p -r1.6 val_anchor.c --- sbin/unwind/libunbound/validator/val_anchor.c 14 Sep 2025 15:16:53 -0000 1.6 +++ sbin/unwind/libunbound/validator/val_anchor.c 21 Sep 2026 16:28:29 -0000 @@ -534,7 +534,10 @@ readkeyword_bindfile(FILE* in, sldns_buf while((c = getc(in)) != EOF ) { if(comments && c == '#') { /* # blabla */ skip_to_eol(in, &c); - if(c == EOF) return 0; + if(c == EOF) { + log_err("trusted-keys, %d, got EOF", *line); + return 0; + } (*line)++; continue; } else if(comments && c=='/' && numdone>0 && /* /_/ bla*/ @@ -543,7 +546,10 @@ readkeyword_bindfile(FILE* in, sldns_buf sldns_buffer_skip(buf, -1); numdone--; skip_to_eol(in, &c); - if(c == EOF) return 0; + if(c == EOF) { + log_err("trusted-keys, %d, got EOF", *line); + return 0; + } (*line)++; continue; } else if(comments && c=='*' && numdone>0 && /* /_* bla *_/ */ @@ -560,7 +566,10 @@ readkeyword_bindfile(FILE* in, sldns_buf if(c == '\n') (*line)++; } - if(c == EOF) return 0; + if(c == EOF) { + log_err("trusted-keys, %d, got EOF", *line); + return 0; + } continue; } /* not a comment, complete the keyword */ @@ -581,7 +590,8 @@ readkeyword_bindfile(FILE* in, sldns_buf } /* space for 1 char + 0 string terminator */ if(sldns_buffer_remaining(buf) < 2) { - fatal_exit("trusted-keys, %d, string too long", *line); + log_err("trusted-keys, %d, string too long", *line); + return 0; } sldns_buffer_write_u8(buf, (uint8_t)c); numdone++; @@ -595,7 +605,10 @@ readkeyword_bindfile(FILE* in, sldns_buf break; } } - if(c == EOF) return 0; + if(c == EOF) { + log_err("trusted-keys, %d, got EOF", *line); + return 0; + } return numdone; } if(is_bind_special(c)) @@ -623,7 +636,7 @@ skip_to_special(FILE* in, sldns_buffer* } return 1; } - log_err("trusted-keys, line %d, expected %c got EOF", *line, spec); + log_err("trusted-keys, line %d, expected %c, read failed", *line, spec); return 0; } Index: sbin/unwind/libunbound/validator/val_neg.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/validator/val_neg.c,v diff -u -p -r1.6 val_neg.c --- sbin/unwind/libunbound/validator/val_neg.c 14 Sep 2025 15:16:53 -0000 1.6 +++ sbin/unwind/libunbound/validator/val_neg.c 21 Sep 2026 16:28:29 -0000 @@ -62,6 +62,13 @@ #include "sldns/rrdef.h" #include "sldns/sbuffer.h" +/** + * The maximum salt length that the negative cache is willing to use. + * Larger salt increases the computation time, while recommendations are + * for zero salt length for zones. + */ +#define MAX_SALT_LENGTH 64 + int val_neg_data_compare(const void* a, const void* b) { struct val_neg_data* x = (struct val_neg_data*)a; @@ -826,7 +833,11 @@ void neg_insert_data(struct val_neg_cach (slen != 0 && zone->nsec3_salt && s && memcmp(zone->nsec3_salt, s, slen) != 0))) { - if(slen > 0) { + if(slen > MAX_SALT_LENGTH) { + /* RFC 9276 s3.1: operators SHOULD NOT use a salt; large + * salts inflate per-hash block count. Decline to cache. */ + return; + } else if(slen > 0) { uint8_t* sa = memdup(s, slen); if(sa) { free(zone->nsec3_salt); @@ -927,6 +938,10 @@ void val_neg_addreply(struct val_neg_cac continue; if(!dname_subdomain_c(rep->rrsets[i]->rk.dname, zone->name)) continue; + if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NSEC && + !nsec_nextowner_subdomain(rep->rrsets[i], zone->name)) { + continue; /* nextowner not in zone */ + } /* insert NSEC into this zone's tree */ neg_insert_data(neg, zone, rep->rrsets[i]); } @@ -1011,6 +1026,10 @@ void val_neg_addreferral(struct val_neg_ continue; if(!dname_subdomain_c(rep->rrsets[i]->rk.dname, zone->name)) continue; + if(ntohs(rep->rrsets[i]->rk.type) == LDNS_RR_TYPE_NSEC && + !nsec_nextowner_subdomain(rep->rrsets[i], zone->name)) { + continue; /* nextowner not in zone */ + } /* insert NSEC into this zone's tree */ neg_insert_data(neg, zone, rep->rrsets[i]); } @@ -1066,11 +1085,7 @@ grab_nsec(struct rrset_cache* rrset_cach qname, qname_len, qtype, qclass, flags, now, 0); struct packed_rrset_data* d; if(!k) return NULL; - d = (struct packed_rrset_data*)k->entry.data; - if(d->ttl < now) { - lock_rw_unlock(&k->entry.lock); - return NULL; - } + d = k->entry.data; /* only secure or unchecked records that have signatures. */ if( ! ( d->security == sec_status_secure || (d->security == sec_status_unchecked && @@ -1103,12 +1118,14 @@ grab_nsec(struct rrset_cache* rrset_cach * @param rrset_cache: rrset cache * @param now: to check ttl against * @param region: where to alloc result + * @param topname: do not look higher than this name, so that the + * result cannot be taken from a zone above the current trust anchor. * @return rrset or NULL */ static struct ub_packed_rrset_key* neg_find_nsec(struct val_neg_cache* neg_cache, uint8_t* qname, size_t qname_len, uint16_t qclass, struct rrset_cache* rrset_cache, time_t now, - struct regional* region) + struct regional* region, uint8_t* topname) { int labs; uint32_t flags; @@ -1126,6 +1143,11 @@ neg_find_nsec(struct val_neg_cache* neg_ lock_basic_unlock(&neg_cache->lock); return NULL; } + if(topname && !dname_subdomain_c(zone->name, topname)) { + /* Reject NSEC not within trust anchor's bailiwick */ + lock_basic_unlock(&neg_cache->lock); + return NULL; + } /* NSEC only for now */ if(zone->nsec3_hash) { @@ -1169,6 +1191,15 @@ neg_find_nsec3_ce(struct val_neg_zone* z uint8_t hashce[NSEC3_SHA_LEN]; uint8_t b32[257]; size_t celen, b32len; + int hashmax = MAX_NSEC3_CALCULATIONS; + if(qlabs > hashmax) { + /* strip leading labels so the walk costs at most + * MAX_NSEC3_CALCULATIONS hashes, mirroring val_nsec3.c */ + while(qlabs > hashmax) { + dname_remove_label(&qname, &qname_len); + qlabs--; + } + } *nclen = 0; while(qlabs > 0) { @@ -1207,8 +1238,8 @@ neg_params_ok(struct val_neg_zone* zone, return 0; return (h == zone->nsec3_hash && it == zone->nsec3_iter && slen == zone->nsec3_saltlen && - (slen != 0 && zone->nsec3_salt && s - && memcmp(zone->nsec3_salt, s, slen) == 0)); + (slen == 0 || (slen != 0 && zone->nsec3_salt && s + && memcmp(zone->nsec3_salt, s, slen) == 0))); } /** get next closer for nsec3 proof */ @@ -1269,6 +1300,12 @@ neg_nsec3_proof_ds(struct val_neg_zone* if(!zone->nsec3_hash) return NULL; /* not nsec3 zone */ + if(!topname && qlabs > zone->labs + 1) + return NULL; /* iterator caller; opt-out proof would be discarded + * at the !topname check below anyway. + * The qlabs check allows the exact-match for + * the one-label-below-zone case. */ + if(!(data=neg_find_nsec3_ce(zone, qname, qname_len, qlabs, buf, hashnc, &nclen))) { return NULL; @@ -1291,8 +1328,10 @@ neg_nsec3_proof_ds(struct val_neg_zone* !nsec3_has_type(ce_rrset, 0, LDNS_RR_TYPE_NS)) return NULL; if(!(msg = dns_msg_create(qname, qname_len, - LDNS_RR_TYPE_DS, zone->dclass, region, 1))) + LDNS_RR_TYPE_DS, zone->dclass, region, 2))) /* ce + soa */ return NULL; + /* The cache response means recursion is available. */ + msg->rep->flags |= BIT_RA; /* TTL reduced in grab_nsec */ if(!dns_msg_authadd(msg, region, ce_rrset, 0)) return NULL; @@ -1327,6 +1366,8 @@ neg_nsec3_proof_ds(struct val_neg_zone* if(!(msg = dns_msg_create(qname, qname_len, LDNS_RR_TYPE_DS, zone->dclass, region, 3))) return NULL; + /* The cache response means recursion is available. */ + msg->rep->flags |= BIT_RA; /* now=0 because TTL was reduced in grab_nsec */ if(!dns_msg_authadd(msg, region, ce_rrset, 0)) return NULL; @@ -1404,7 +1445,7 @@ val_neg_getmsg(struct val_neg_cache* neg /* Get best available NSEC for qname */ nsec = neg_find_nsec(neg, qinfo->qname, qinfo->qname_len, qinfo->qclass, - rrset_cache, now, region); + rrset_cache, now, region, topname); /* Matching NSEC, use to generate No Data answer. Not creating answers * yet for No Data proven using wildcard. */ @@ -1417,6 +1458,8 @@ val_neg_getmsg(struct val_neg_cache* neg if(!(msg = dns_msg_create(qinfo->qname, qinfo->qname_len, qinfo->qtype, qinfo->qclass, region, 2))) return NULL; + /* The cache response means recursion is available. */ + msg->rep->flags |= BIT_RA; if(!dns_msg_authadd(msg, region, nsec, 0)) return NULL; if(addsoa && !add_soa(rrset_cache, now, region, msg, NULL)) @@ -1430,6 +1473,8 @@ val_neg_getmsg(struct val_neg_cache* neg if(!(msg = dns_msg_create(qinfo->qname, qinfo->qname_len, qinfo->qtype, qinfo->qclass, region, 3))) return NULL; + /* The cache response means recursion is available. */ + msg->rep->flags |= BIT_RA; if(!(ce = nsec_closest_encloser(qinfo->qname, nsec))) return NULL; dname_count_size_labels(ce, &ce_len); @@ -1480,7 +1525,7 @@ val_neg_getmsg(struct val_neg_cache* neg * proof */ if(!(wcrr = neg_find_nsec(neg, wc_qinfo.qname, wc_qinfo.qname_len, qinfo->qclass, - rrset_cache, now, region))) + rrset_cache, now, region, topname))) return NULL; nodata_wc = NULL; Index: sbin/unwind/libunbound/validator/val_nsec.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/validator/val_nsec.c,v diff -u -p -r1.7 val_nsec.c --- sbin/unwind/libunbound/validator/val_nsec.c 5 Sep 2024 08:22:48 -0000 1.7 +++ sbin/unwind/libunbound/validator/val_nsec.c 21 Sep 2026 16:28:29 -0000 @@ -177,7 +177,8 @@ static int nsec_verify_rrset(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key* nsec, struct key_entry_key* kkey, char** reason, sldns_ede_code* reason_bogus, - struct module_qstate* qstate, char* reasonbuf, size_t reasonlen) + struct module_qstate* qstate, struct val_qstate* vq, char* reasonbuf, + size_t reasonlen) { struct packed_rrset_data* d = (struct packed_rrset_data*) nsec->entry.data; @@ -189,7 +190,7 @@ nsec_verify_rrset(struct module_env* env if(d->security == sec_status_secure) return 1; d->security = val_verify_rrset_entry(env, ve, nsec, kkey, reason, - reason_bogus, LDNS_SECTION_AUTHORITY, qstate, &verified, + reason_bogus, LDNS_SECTION_AUTHORITY, qstate, vq, &verified, reasonbuf, reasonlen); if(d->security == sec_status_secure) { rrset_update_sec_status(env->rrset_cache, nsec, *env->now); @@ -203,7 +204,7 @@ val_nsec_prove_nodata_dsreply(struct mod struct query_info* qinfo, struct reply_info* rep, struct key_entry_key* kkey, time_t* proof_ttl, char** reason, sldns_ede_code* reason_bogus, struct module_qstate* qstate, - char* reasonbuf, size_t reasonlen) + struct val_qstate* vq, char* reasonbuf, size_t reasonlen) { struct ub_packed_rrset_key* nsec = reply_find_rrset_section_ns( rep, qinfo->qname, qinfo->qname_len, LDNS_RR_TYPE_NSEC, @@ -221,26 +222,32 @@ val_nsec_prove_nodata_dsreply(struct mod * 2) this is not a delegation point */ if(nsec) { if(!nsec_verify_rrset(env, ve, nsec, kkey, reason, - reason_bogus, qstate, reasonbuf, reasonlen)) { + reason_bogus, qstate, vq, reasonbuf, reasonlen)) { verbose(VERB_ALGO, "NSEC RRset for the " "referral did not verify."); return sec_status_bogus; } - sec = val_nsec_proves_no_ds(nsec, qinfo); - if(sec == sec_status_bogus) { - /* something was wrong. */ - *reason = "NSEC does not prove absence of DS"; - *reason_bogus = LDNS_EDE_DNSSEC_BOGUS; - return sec; - } else if(sec == sec_status_insecure) { - /* this wasn't a delegation point. */ - return sec; - } else if(sec == sec_status_secure) { - /* this proved no DS. */ - *proof_ttl = ub_packed_rrset_ttl(nsec); - return sec; + /* If the NSEC was a wildcard, the verify rewrites the + * owner to '*.zone'. Check the NSEC owner matches. */ + if(query_dname_compare(nsec->rk.dname, qinfo->qname) == 0) { + sec = val_nsec_proves_no_ds(nsec, qinfo); + if(sec == sec_status_bogus) { + /* something was wrong. */ + *reason = "NSEC does not prove absence of DS"; + *reason_bogus = LDNS_EDE_DNSSEC_BOGUS; + return sec; + } else if(sec == sec_status_insecure) { + /* this wasn't a delegation point. */ + return sec; + } else if(sec == sec_status_secure) { + /* this proved no DS. */ + *proof_ttl = ub_packed_rrset_ttl(nsec); + return sec; + } } /* if unchecked, fall through to next proof */ + /* For *.closest-encloser NSEC, there is a closer-match + * check for the wildcard below. */ } /* Otherwise, there is no NSEC at qname. This could be an ENT. @@ -252,7 +259,7 @@ val_nsec_prove_nodata_dsreply(struct mod if(rep->rrsets[i]->rk.type != htons(LDNS_RR_TYPE_NSEC)) continue; if(!nsec_verify_rrset(env, ve, rep->rrsets[i], kkey, reason, - reason_bogus, qstate, reasonbuf, reasonlen)) { + reason_bogus, qstate, vq, reasonbuf, reasonlen)) { verbose(VERB_ALGO, "NSEC for empty non-terminal " "did not verify."); *reason = "NSEC for empty non-terminal " Index: sbin/unwind/libunbound/validator/val_nsec.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/validator/val_nsec.h,v diff -u -p -r1.4 val_nsec.h --- sbin/unwind/libunbound/validator/val_nsec.h 5 Sep 2024 08:22:48 -0000 1.4 +++ sbin/unwind/libunbound/validator/val_nsec.h 21 Sep 2026 16:28:29 -0000 @@ -52,6 +52,7 @@ struct ub_packed_rrset_key; struct reply_info; struct query_info; struct key_entry_key; +struct val_qstate; /** * Check DS absence. @@ -68,6 +69,7 @@ struct key_entry_key; * @param reason: string explaining why bogus. * @param reason_bogus: relevant EDE code for validation failure. * @param qstate: qstate with region. + * @param vq: validator qstate. * @param reasonbuf: buffer to use for fail reason string print. * @param reasonlen: length of reasonbuf. * @return security status. @@ -80,7 +82,8 @@ enum sec_status val_nsec_prove_nodata_ds struct val_env* ve, struct query_info* qinfo, struct reply_info* rep, struct key_entry_key* kkey, time_t* proof_ttl, char** reason, sldns_ede_code* reason_bogus, - struct module_qstate* qstate, char* reasonbuf, size_t reasonlen); + struct module_qstate* qstate, struct val_qstate* vq, char* reasonbuf, + size_t reasonlen); /** * nsec typemap check, takes an NSEC-type bitmap as argument, checks for type. Index: sbin/unwind/libunbound/validator/val_nsec3.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/validator/val_nsec3.c,v diff -u -p -r1.5 val_nsec3.c --- sbin/unwind/libunbound/validator/val_nsec3.c 23 Feb 2025 07:53:40 -0000 1.5 +++ sbin/unwind/libunbound/validator/val_nsec3.c 21 Sep 2026 16:28:30 -0000 @@ -60,11 +60,6 @@ #include "util/config_file.h" /** - * Max number of NSEC3 calculations at once, suspend query for later. - * 8 is low enough and allows for cases where multiple proofs are needed. - */ -#define MAX_NSEC3_CALCULATIONS 8 -/** * When all allowed NSEC3 calculations at once resulted in error treat as * bogus. NSEC3 hash errors are not cached and this helps breaks loops with * erroneous data. @@ -456,6 +451,67 @@ filter_init(struct nsec3_filter* filter, } } +/** Check if the NSEC3s have the same parameter set. */ +static int +param_set_same(struct nsec3_filter* flt, char** reason) +{ + size_t rrsetnum; + int rrnum; + struct ub_packed_rrset_key* rrset; + int have_params = 0; + int first_algo = 0; + size_t first_iter = 0; + uint8_t* first_salt = NULL; + size_t first_saltlen = 0; + + /* If the NSEC3 parameter sets have distinct values, then they are + * from different NSEC3 chains, and we do not want that. */ + for(rrset=filter_first(flt, &rrsetnum, &rrnum); rrset; + rrset=filter_next(flt, &rrsetnum, &rrnum)) { + if(!have_params) { + first_algo = nsec3_get_algo(rrset, rrnum); + first_iter = nsec3_get_iter(rrset, rrnum); + if(!nsec3_get_salt(rrset, rrnum, &first_salt, + &first_saltlen)) { + verbose(VERB_ALGO, "NSEC3 salt malformed"); + if(reason) + *reason = "NSEC3 salt malformed"; + return 0; + } + have_params = 1; + } else { + uint8_t* salt = NULL; + size_t saltlen = 0; + if(nsec3_get_algo(rrset, rrnum) != first_algo) { + verbose(VERB_ALGO, "NSEC3 algorithm mismatch"); + if(reason) + *reason = "NSEC3 algorithm mismatch"; + return 0; + } + if(nsec3_get_iter(rrset, rrnum) != first_iter) { + verbose(VERB_ALGO, "NSEC3 iterations mismatch"); + if(reason) + *reason = "NSEC3 iterations mismatch"; + return 0; + } + if(!nsec3_get_salt(rrset, rrnum, &salt, &saltlen)) { + verbose(VERB_ALGO, "NSEC3 salt malformed"); + if(reason) + *reason = "NSEC3 salt malformed"; + return 0; + } + if(saltlen != first_saltlen || + memcmp(salt, first_salt, saltlen) != 0) { + verbose(VERB_ALGO, "NSEC3 salt mismatch"); + if(reason) + *reason = "NSEC3 salt mismatch"; + return 0; + } + } + } + return 1; +} + /** * Find max iteration count using config settings and key size * @param ve: validator environment with iteration count config settings. @@ -1192,6 +1248,12 @@ nsec3_prove_nameerror(struct module_env* filter_init(&flt, list, num, qinfo); /* init RR iterator */ if(!flt.zone) return sec_status_bogus; /* no RRs */ + if(query_dname_compare(flt.zone, kkey->name) != 0) { + verbose(VERB_ALGO, "NSEC3 name is not b32.signer name"); + return sec_status_bogus; + } + if(!param_set_same(&flt, NULL)) + return sec_status_bogus; /* nsec3 params from distinct chains*/ if(nsec3_iteration_count_high(ve, &flt, kkey)) return sec_status_insecure; /* iteration count too high */ log_nametypeclass(VERB_ALGO, "start nsec3 nameerror proof, zone", @@ -1378,6 +1440,12 @@ nsec3_prove_nodata(struct module_env* en filter_init(&flt, list, num, qinfo); /* init RR iterator */ if(!flt.zone) return sec_status_bogus; /* no RRs */ + if(query_dname_compare(flt.zone, kkey->name) != 0) { + verbose(VERB_ALGO, "NSEC3 name is not b32.signer name"); + return sec_status_bogus; + } + if(!param_set_same(&flt, NULL)) + return sec_status_bogus; /* nsec3 params from distinct chains*/ if(nsec3_iteration_count_high(ve, &flt, kkey)) return sec_status_insecure; /* iteration count too high */ return nsec3_do_prove_nodata(env, &flt, ct, qinfo, calc); @@ -1401,6 +1469,12 @@ nsec3_prove_wildcard(struct module_env* filter_init(&flt, list, num, qinfo); /* init RR iterator */ if(!flt.zone) return sec_status_bogus; /* no RRs */ + if(query_dname_compare(flt.zone, kkey->name) != 0) { + verbose(VERB_ALGO, "NSEC3 name is not b32.signer name"); + return sec_status_bogus; + } + if(!param_set_same(&flt, NULL)) + return sec_status_bogus; /* nsec3 params from distinct chains*/ if(nsec3_iteration_count_high(ve, &flt, kkey)) return sec_status_insecure; /* iteration count too high */ @@ -1447,7 +1521,8 @@ static int list_is_secure(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key** list, size_t num, struct key_entry_key* kkey, char** reason, sldns_ede_code *reason_bogus, - struct module_qstate* qstate, char* reasonbuf, size_t reasonlen) + struct module_qstate* qstate, struct val_qstate* vq, char* reasonbuf, + size_t reasonlen) { struct packed_rrset_data* d; size_t i; @@ -1463,7 +1538,7 @@ list_is_secure(struct module_env* env, s continue; d->security = val_verify_rrset_entry(env, ve, list[i], kkey, reason, reason_bogus, LDNS_SECTION_AUTHORITY, qstate, - &verified, reasonbuf, reasonlen); + vq, &verified, reasonbuf, reasonlen); if(d->security != sec_status_secure) { verbose(VERB_ALGO, "NSEC3 did not verify"); return 0; @@ -1478,7 +1553,8 @@ nsec3_prove_nods(struct module_env* env, struct ub_packed_rrset_key** list, size_t num, struct query_info* qinfo, struct key_entry_key* kkey, char** reason, sldns_ede_code* reason_bogus, struct module_qstate* qstate, - struct nsec3_cache_table* ct, char* reasonbuf, size_t reasonlen) + struct val_qstate* vq, struct nsec3_cache_table* ct, char* reasonbuf, + size_t reasonlen) { struct nsec3_filter flt; struct ce_response ce; @@ -1494,7 +1570,7 @@ nsec3_prove_nods(struct module_env* env, return sec_status_bogus; /* no valid NSEC3s, bogus */ } if(!list_is_secure(env, ve, list, num, kkey, reason, reason_bogus, - qstate, reasonbuf, reasonlen)) { + qstate, vq, reasonbuf, reasonlen)) { *reason = "not all NSEC3 records secure"; return sec_status_bogus; /* not all NSEC3 records secure */ } @@ -1503,6 +1579,13 @@ nsec3_prove_nods(struct module_env* env, *reason = "no NSEC3 records"; return sec_status_bogus; /* no RRs */ } + if(query_dname_compare(flt.zone, kkey->name) != 0) { + verbose(VERB_ALGO, "NSEC3 name is not b32.signer name"); + *reason = "NSEC3 name is not b32.signer name"; + return sec_status_bogus; + } + if(!param_set_same(&flt, reason)) + return sec_status_bogus; /* nsec3 params from distinct chains*/ if(nsec3_iteration_count_high(ve, &flt, kkey)) return sec_status_insecure; /* iteration count too high */ @@ -1596,6 +1679,12 @@ nsec3_prove_nxornodata(struct module_env filter_init(&flt, list, num, qinfo); /* init RR iterator */ if(!flt.zone) return sec_status_bogus; /* no RRs */ + if(query_dname_compare(flt.zone, kkey->name) != 0) { + verbose(VERB_ALGO, "NSEC3 name is not b32.signer name"); + return sec_status_bogus; + } + if(!param_set_same(&flt, NULL)) + return sec_status_bogus; /* nsec3 params from distinct chains*/ if(nsec3_iteration_count_high(ve, &flt, kkey)) return sec_status_insecure; /* iteration count too high */ Index: sbin/unwind/libunbound/validator/val_nsec3.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/validator/val_nsec3.h,v diff -u -p -r1.4 val_nsec3.h --- sbin/unwind/libunbound/validator/val_nsec3.h 5 Sep 2024 08:22:48 -0000 1.4 +++ sbin/unwind/libunbound/validator/val_nsec3.h 21 Sep 2026 16:28:30 -0000 @@ -78,6 +78,7 @@ struct reply_info; struct query_info; struct key_entry_key; struct sldns_buffer; +struct val_qstate; /** * 0 1 2 3 4 5 6 7 @@ -99,6 +100,12 @@ struct sldns_buffer; #define NSEC3_HASH_SHA1 0x01 /** + * Max number of NSEC3 calculations at once, suspend query for later. + * 8 is low enough and allows for cases where multiple proofs are needed. + */ +#define MAX_NSEC3_CALCULATIONS 8 + +/** * Cache table for NSEC3 hashes. * It keeps a *pointer* to the region its items are allocated. */ @@ -209,6 +216,7 @@ nsec3_prove_wildcard(struct module_env* * @param reason: string for bogus result. * @param reason_bogus: EDE (RFC8914) code paired with the reason of failure. * @param qstate: qstate with region. + * @param vq: validator qstate. * @param ct: cached hashes table. * @param reasonbuf: buffer to use for fail reason string print. * @param reasonlen: length of reasonbuf. @@ -224,7 +232,8 @@ nsec3_prove_nods(struct module_env* env, struct ub_packed_rrset_key** list, size_t num, struct query_info* qinfo, struct key_entry_key* kkey, char** reason, sldns_ede_code* reason_bogus, struct module_qstate* qstate, - struct nsec3_cache_table* ct, char* reasonbuf, size_t reasonlen); + struct val_qstate* vq, struct nsec3_cache_table* ct, char* reasonbuf, + size_t reasonlen); /** * Prove NXDOMAIN or NODATA. Index: sbin/unwind/libunbound/validator/val_secalgo.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/validator/val_secalgo.c,v diff -u -p -r1.8 val_secalgo.c --- sbin/unwind/libunbound/validator/val_secalgo.c 5 Sep 2024 08:22:48 -0000 1.8 +++ sbin/unwind/libunbound/validator/val_secalgo.c 21 Sep 2026 16:28:30 -0000 @@ -745,11 +745,9 @@ verify_canonrrset(sldns_buffer* buf, int if((algo == LDNS_DSA || algo == LDNS_DSA_NSEC3) &&(fake_dsa||fake_sha1)) return sec_status_secure; #endif -#ifndef USE_SHA1 if(fake_sha1 && (algo == LDNS_DSA || algo == LDNS_DSA_NSEC3 || algo == LDNS_RSASHA1 || algo == LDNS_RSASHA1_NSEC3)) return sec_status_secure; -#endif - + if(!setup_key_digest(algo, &evp_key, &digest_type, key, keylen)) { verbose(VERB_QUERY, "verify: failed to setup key"); *reason = "use of key for crypto failed"; @@ -1874,9 +1872,9 @@ _verify_nettle_rsa(sldns_buffer* buf, un } mod_offset = exp_offset + exp_len; nettle_rsa_public_key_init(&pubkey); - pubkey.size = keylen - mod_offset; nettle_mpz_set_str_256_u(pubkey.e, exp_len, &key[exp_offset]); - nettle_mpz_set_str_256_u(pubkey.n, pubkey.size, &key[mod_offset]); + nettle_mpz_set_str_256_u(pubkey.n, keylen - mod_offset, &key[mod_offset]); + pubkey.size = nettle_mpz_sizeinbase_256_u(pubkey.n); /* Digest content of "buf" and verify its RSA signature in "sigblock"*/ nettle_mpz_init_set_str_256_u(signature, sigblock_len, (uint8_t*)sigblock); Index: sbin/unwind/libunbound/validator/val_sigcrypt.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/validator/val_sigcrypt.c,v diff -u -p -r1.11 val_sigcrypt.c --- sbin/unwind/libunbound/validator/val_sigcrypt.c 29 Sep 2025 14:53:38 -0000 1.11 +++ sbin/unwind/libunbound/validator/val_sigcrypt.c 21 Sep 2026 16:28:30 -0000 @@ -82,6 +82,8 @@ /** Maximum number of RRSIG validations for an RRset. */ #define MAX_VALIDATE_RRSIGS 8 +/** Maximum number of NSEC validations for a message. */ +#define MAX_VALIDATE_NSECS 8 /** return number of rrs in an rrset */ static size_t @@ -305,6 +307,8 @@ ds_create_dnskey_digest(struct module_en * digest = digest_algorithm( DNSKEY owner name | DNSKEY RDATA); * DNSKEY RDATA = Flags | Protocol | Algorithm | Public Key. */ sldns_buffer_clear(b); + if(!sldns_buffer_available(b, dnskey_rrset->rk.dname_len + dnskey_len-2)) + return 0; /* buffer too small */ sldns_buffer_write(b, dnskey_rrset->rk.dname, dnskey_rrset->rk.dname_len); query_dname_tolower(sldns_buffer_begin(b)); @@ -546,8 +550,10 @@ int algo_needs_missing(struct algo_needs * @param reason_bogus: EDE (RFC8914) code paired with the reason of failure. * @param section: section of packet where this rrset comes from. * @param qstate: qstate with region. + * @param vq: validator qstate with attempt counts. * @param numverified: incremented when the number of RRSIG validations * increases. + * @param num_tagmatches: incremented for tag matches. * @return secure if any key signs *this* signature. bogus if no key signs it, * unchecked on error, or indeterminate if all keys are not supported by * the crypto library (openssl3+ only). @@ -559,7 +565,7 @@ dnskeyset_verify_rrset_sig(struct module struct rbtree_type** sortree, char** reason, sldns_ede_code *reason_bogus, sldns_pkt_section section, struct module_qstate* qstate, - int* numverified) + struct val_qstate* vq, int* numverified, size_t* num_tagmatches) { /* find matching keys and check them */ enum sec_status sec = sec_status_bogus; @@ -578,6 +584,14 @@ dnskeyset_verify_rrset_sig(struct module } for(i=0; i MAX_TAG_MATCHES) { + *reason = "too many tag matches"; + if(reason_bogus) + *reason_bogus = LDNS_EDE_DNSSEC_BOGUS; + verbose(VERB_ALGO, "verify sig: too many tag matches, " + "MAX_TAG_MATCHES (%d); bogus", MAX_TAG_MATCHES); + return sec_status_bogus; + } /* see if key matches keytag and algo */ if(algo != dnskey_get_algo(dnskey, i) || tag != dnskey_calc_keytag(dnskey, i)) @@ -585,6 +599,26 @@ dnskeyset_verify_rrset_sig(struct module numchecked ++; (*numverified)++; + if(vq && vq->num_validation_attempts++ > env->cfg->val_validation_attempts) { + *reason = "too many validation attempts"; + if(reason_bogus) + *reason_bogus = LDNS_EDE_DNSSEC_BOGUS; + verbose(VERB_ALGO, "verify sig: too many validation attempts, " + "val-validation-attempts (%d); bogus", env->cfg->val_validation_attempts); + return sec_status_bogus; + } + if(vq && (ntohs(rrset->rk.type) == LDNS_RR_TYPE_NSEC || + ntohs(rrset->rk.type) == LDNS_RR_TYPE_NSEC3) && + vq->num_nsec_attempts++ > MAX_VALIDATE_NSECS) { + *reason = "too many NSEC or NSEC3 validation attempts"; + if(reason_bogus) + *reason_bogus = LDNS_EDE_DNSSEC_BOGUS; + verbose(VERB_ALGO, "verify sig: too many NSEC or NSEC3 validation attempts, " + "(%d); bogus", MAX_VALIDATE_NSECS); + vq->num_nsec_attempts_exceeded = 1; + return sec_status_bogus; + } + /* see if key verifies */ sec = dnskey_verify_rrset_sig(env->scratch, env->scratch_buffer, ve, now, rrset, dnskey, i, @@ -624,11 +658,12 @@ enum sec_status dnskeyset_verify_rrset(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey, uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus, - sldns_pkt_section section, struct module_qstate* qstate, int* verified, - char* reasonbuf, size_t reasonlen) + sldns_pkt_section section, struct module_qstate* qstate, + struct val_qstate* vq, int* verified, char* reasonbuf, + size_t reasonlen) { enum sec_status sec; - size_t i, num; + size_t i, num, num_tagmatches = 0; rbtree_type* sortree = NULL; /* make sure that for all DNSKEY algorithms there are valid sigs */ struct algo_needs needs; @@ -656,9 +691,19 @@ dnskeyset_verify_rrset(struct module_env } } for(i=0; i MAX_TAG_MATCHES) { + *reason = "too many tag matches"; + if(reason_bogus) + *reason_bogus = LDNS_EDE_DNSSEC_BOGUS; + verbose(VERB_ALGO, "rrset failed to verify: too many tag matches, " + "MAX_TAG_MATCHES (%d)", MAX_TAG_MATCHES); + if(reason_bogus) + *reason_bogus = LDNS_EDE_DNSSEC_BOGUS; + return sec_status_bogus; + } sec = dnskeyset_verify_rrset_sig(env, ve, *env->now, rrset, dnskey, i, &sortree, reason, reason_bogus, - section, qstate, verified); + section, qstate, vq, verified, &num_tagmatches); /* see which algorithm has been fixed up */ if(sec == sec_status_secure) { if(!sigalg) @@ -707,7 +752,8 @@ enum sec_status dnskey_verify_rrset(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey, size_t dnskey_idx, char** reason, sldns_ede_code *reason_bogus, - sldns_pkt_section section, struct module_qstate* qstate) + sldns_pkt_section section, struct module_qstate* qstate, + struct val_qstate* vq, size_t* num_tagmatches) { enum sec_status sec; size_t i, num, numchecked = 0, numindeterminate = 0; @@ -728,9 +774,26 @@ dnskey_verify_rrset(struct module_env* e } for(i=0; i MAX_TAG_MATCHES) { + *reason = "too many tag matches"; + if(reason_bogus) + *reason_bogus = LDNS_EDE_DNSSEC_BOGUS; + verbose(VERB_ALGO, "rrset failed to verify: too many tag matches, " + "MAX_TAG_MATCHES (%d); bogus", MAX_TAG_MATCHES); + return sec_status_bogus; + } if(algo != rrset_get_sig_algo(rrset, i) || tag != rrset_get_sig_keytag(rrset, i)) continue; + if(vq && vq->num_validation_attempts++ > env->cfg->val_validation_attempts) { + *reason = "too many validation attempts"; + if(reason_bogus) + *reason_bogus = LDNS_EDE_DNSSEC_BOGUS; + verbose(VERB_ALGO, "rrset failed to verify: too many validation attempts, " + "val-validation-attempts (%d); bogus", env->cfg->val_validation_attempts); + return sec_status_bogus; + } + buf_canon = 0; sec = dnskey_verify_rrset_sig(env->scratch, env->scratch_buffer, ve, *env->now, rrset, @@ -1083,6 +1146,18 @@ insert_can_owner(sldns_buffer* buf, stru } } +/** lowercase a wire dname but never step past end */ +static void +canon_dname_tolower(uint8_t* d, uint8_t* end) +{ + uint8_t lab; + while(d < end && (lab = *d) != 0) { + if((size_t)lab+1 > (size_t)(end-d)) return; /* malformed */ + for(d++; lab; lab--, d++) + *d = (uint8_t)tolower((unsigned char)*d); + } +} + /** * Canonicalize Rdata in buffer. * @param buf: buffer at position just after the rdata. @@ -1094,6 +1169,8 @@ canonicalize_rdata(sldns_buffer* buf, st size_t len) { uint8_t* datstart = sldns_buffer_current(buf)-len+2; + uint8_t* datend = sldns_buffer_current(buf); + size_t firstlen; switch(ntohs(rrset->rk.type)) { case LDNS_RR_TYPE_NXT: case LDNS_RR_TYPE_NS: @@ -1106,15 +1183,16 @@ canonicalize_rdata(sldns_buffer* buf, st case LDNS_RR_TYPE_PTR: case LDNS_RR_TYPE_DNAME: /* type only has a single argument, the name */ - query_dname_tolower(datstart); + canon_dname_tolower(datstart, datend); return; case LDNS_RR_TYPE_MINFO: case LDNS_RR_TYPE_RP: case LDNS_RR_TYPE_SOA: /* two names after another */ - query_dname_tolower(datstart); - query_dname_tolower(datstart + - dname_valid(datstart, len-2)); + canon_dname_tolower(datstart, datend); + firstlen = dname_valid(datstart, len-2); + if(firstlen && firstlen < len-2) + canon_dname_tolower(datstart + firstlen, datend); return; case LDNS_RR_TYPE_RT: case LDNS_RR_TYPE_AFSDB: @@ -1124,7 +1202,7 @@ canonicalize_rdata(sldns_buffer* buf, st if(len < 2+2+1) /* rdlen, skiplen, 1byteroot */ return; datstart += 2; - query_dname_tolower(datstart); + canon_dname_tolower(datstart, datend); return; case LDNS_RR_TYPE_SIG: /* downcase the RRSIG, compat with BIND (kept it from SIG) */ @@ -1133,16 +1211,17 @@ canonicalize_rdata(sldns_buffer* buf, st if(len < 2+18+1) return; datstart += 18; - query_dname_tolower(datstart); + canon_dname_tolower(datstart, datend); return; case LDNS_RR_TYPE_PX: /* skip, then two names after another */ if(len < 2+2+1) return; datstart += 2; - query_dname_tolower(datstart); - query_dname_tolower(datstart + - dname_valid(datstart, len-2-2)); + canon_dname_tolower(datstart, datend); + firstlen = dname_valid(datstart, len-2-2); + if(firstlen && firstlen < len-2-2) + canon_dname_tolower(datstart + firstlen, datend); return; case LDNS_RR_TYPE_NAPTR: if(len < 2+4) @@ -1163,14 +1242,14 @@ canonicalize_rdata(sldns_buffer* buf, st datstart += (size_t)datstart[0]+1; if(len < 1) /* check name is at least 1 byte*/ return; - query_dname_tolower(datstart); + canon_dname_tolower(datstart, datend); return; case LDNS_RR_TYPE_SRV: /* skip fixed part */ if(len < 2+6+1) return; datstart += 6; - query_dname_tolower(datstart); + canon_dname_tolower(datstart, datend); return; /* do not canonicalize NSEC rdata name, compat with @@ -1292,14 +1371,32 @@ rrset_canonical(struct regional* region, } sldns_buffer_clear(buf); + if(sldns_buffer_remaining(buf) < siglen || siglen < 18+1) { + verbose(VERB_ALGO, "verify: failed to canonicalize, " + "rrset too big"); + return 0; + } sldns_buffer_write(buf, sig, siglen); /* canonicalize signer name */ - query_dname_tolower(sldns_buffer_begin(buf)+18); + canon_dname_tolower(sldns_buffer_begin(buf)+18, + sldns_buffer_current(buf)); + + if(sldns_buffer_remaining(buf) < k->rk.dname_len+2) { + /* Check if the first can_owner name can fit in the buffer. + * The length is k->rk.dname_len or k->rk.dname_len+2 + * if it has '*.' in prefixed. Checks the upper bound, + * also realistically the rest of the rrtype, rrclass, origttl, + * rdata and so on has to be inserted, so that extra space has + * to be there. */ + verbose(VERB_ALGO, "verify: failed to canonicalize, " + "rrset too big"); + return 0; + } RBTREE_FOR(walk, struct canon_rr*, (*sortree)) { /* see if there is enough space left in the buffer */ if(sldns_buffer_remaining(buf) < can_owner_len + 2 + 2 + 4 + d->rr_len[walk->rr_idx]) { - log_err("verify: failed to canonicalize, " + verbose(VERB_ALGO, "verify: failed to canonicalize, " "rrset too big"); return 0; } @@ -1308,6 +1405,13 @@ rrset_canonical(struct regional* region, sldns_buffer_write(buf, can_owner, can_owner_len); else insert_can_owner(buf, k, sig, &can_owner, &can_owner_len); + /* Check again, if the rdata can fit in the buffer */ + if(sldns_buffer_remaining(buf) < 2 + 2 + 4 + + d->rr_len[walk->rr_idx]) { + verbose(VERB_ALGO, "verify: failed to canonicalize, " + "rrset too big"); + return 0; + } sldns_buffer_write(buf, &k->rk.type, 2); sldns_buffer_write(buf, &k->rk.rrset_class, 2); sldns_buffer_write(buf, sig+4, 4); @@ -1322,10 +1426,11 @@ rrset_canonical(struct regional* region, * the non-existence proves. */ if(ntohs(k->rk.type) == LDNS_RR_TYPE_NSEC && section == LDNS_SECTION_AUTHORITY && qstate) { - k->rk.dname = regional_alloc_init(qstate->region, can_owner, + uint8_t* new_dname = regional_alloc_init(qstate->region, can_owner, can_owner_len); - if(!k->rk.dname) + if(!new_dname) return 0; + k->rk.dname = new_dname; k->rk.dname_len = can_owner_len; } @@ -1358,11 +1463,17 @@ rrset_canonicalize_to_buffer(struct regi canonical_sort(k, d, sortree, rrs); sldns_buffer_clear(buf); + if(sldns_buffer_remaining(buf) < k->rk.dname_len) { + /* Check if the first can_owner name can fit in the buffer. */ + verbose(VERB_ALGO, "verify: failed to canonicalize, " + "rrset too big"); + return 0; + } RBTREE_FOR(walk, struct canon_rr*, sortree) { /* see if there is enough space left in the buffer */ if(sldns_buffer_remaining(buf) < can_owner_len + 2 + 2 + 4 + d->rr_len[walk->rr_idx]) { - log_err("verify: failed to canonicalize, " + verbose(VERB_ALGO, "verify: failed to canonicalize, " "rrset too big"); return 0; } @@ -1375,6 +1486,13 @@ rrset_canonicalize_to_buffer(struct regi query_dname_tolower(can_owner); can_owner_len = k->rk.dname_len; } + /* Check again, if the rdata can fit in the buffer */ + if(sldns_buffer_remaining(buf) < 2 + 2 + 4 + + d->rr_len[walk->rr_idx]) { + verbose(VERB_ALGO, "verify: failed to canonicalize, " + "rrset too big"); + return 0; + } sldns_buffer_write(buf, &k->rk.type, 2); sldns_buffer_write(buf, &k->rk.rrset_class, 2); sldns_buffer_write_u32(buf, d->rr_ttl[walk->rr_idx]); @@ -1570,6 +1688,18 @@ dnskey_verify_rrset_sig(struct regional* *reason_bogus = LDNS_EDE_NO_ZONE_KEY_BIT_SET; return sec_status_bogus; } + if((dnskey_get_flags(dnskey, dnskey_idx) & LDNS_KEY_REVOKE_KEY) && + /* The REVOKE key is allowed to check sigs on itself. */ + !(ntohs(rrset->rk.type) == LDNS_RR_TYPE_DNSKEY && + query_dname_compare(rrset->rk.dname, dnskey->rk.dname)==0) + ) { + verbose(VERB_QUERY, "verify: dnskey has REVOKE bit set, " + "not usable for data validation per RFC 5011 s2.1"); + *reason = "dnskey revoked"; + if(reason_bogus) + *reason_bogus = LDNS_EDE_DNSKEY_MISSING; + return sec_status_bogus; + } if(dnskey_get_protocol(dnskey, dnskey_idx) != LDNS_DNSSEC_KEYPROTO) { /* RFC 4034 says DNSKEY PROTOCOL MUST be 3 */ @@ -1597,6 +1727,30 @@ dnskey_verify_rrset_sig(struct regional* *reason_bogus = LDNS_EDE_DNSSEC_BOGUS; return sec_status_bogus; /* signer name offtree */ } + /* NSEC3, the owner name must be the .signername */ + if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_NSEC3 && + rrset->rk.dname_len > 0) { + uint8_t* dnameless = rrset->rk.dname; + size_t dnamelesslen = rrset->rk.dname_len; + dname_remove_label(&dnameless, &dnamelesslen); + if(query_dname_compare(dnameless, signer) != 0) { + verbose(VERB_QUERY, "verify: NSEC3 owner name is not b32.signer name"); + *reason = "NSEC3 owner name is not b32.signer name"; + if(reason_bogus) + *reason_bogus = LDNS_EDE_DNSSEC_BOGUS; + return sec_status_bogus; /* NSEC3 owner not b32.signer */ + } + } + /* NSEC, a next owner that is not under the signer is not allowed.*/ + if(ntohs(rrset->rk.type) == LDNS_RR_TYPE_NSEC && + !nsec_nextowner_subdomain(rrset, signer)) { + verbose(VERB_QUERY, "verify: NSEC next owner overreaches signer name"); + *reason = "NSEC next owner overreaches signer name"; + if(reason_bogus) + *reason_bogus = LDNS_EDE_DNSSEC_BOGUS; + return sec_status_bogus; /* nextowner overreaching */ + } + sigblock = (unsigned char*)signer+signer_len; if(siglen < 2+18+signer_len+1) { verbose(VERB_QUERY, "verify: too short, no signature data"); @@ -1650,6 +1804,13 @@ dnskey_verify_rrset_sig(struct regional* if((int)sig[2+3] > dname_signame_label_count(rrset->rk.dname)) { verbose(VERB_QUERY, "verify: labelcount out of range"); *reason = "signature labelcount out of range"; + if(reason_bogus) + *reason_bogus = LDNS_EDE_DNSSEC_BOGUS; + return sec_status_bogus; + } + if((int)sig[2+3] < dname_signame_label_count(signer)) { + verbose(VERB_QUERY, "verify: RRSIG label count too low for signer"); + *reason = "signature labelcount lower than signature signer"; if(reason_bogus) *reason_bogus = LDNS_EDE_DNSSEC_BOGUS; return sec_status_bogus; Index: sbin/unwind/libunbound/validator/val_sigcrypt.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/validator/val_sigcrypt.h,v diff -u -p -r1.5 val_sigcrypt.h --- sbin/unwind/libunbound/validator/val_sigcrypt.h 5 Sep 2024 08:22:48 -0000 1.5 +++ sbin/unwind/libunbound/validator/val_sigcrypt.h 21 Sep 2026 16:28:30 -0000 @@ -53,6 +53,7 @@ struct ub_packed_rrset_key; struct rbtree_type; struct regional; struct sldns_buffer; +struct val_qstate; /** number of entries in algorithm needs array */ #define ALGO_NEEDS_MAX 256 @@ -262,6 +263,7 @@ uint16_t dnskey_get_flags(struct ub_pack * @param reason_bogus: EDE (RFC8914) code paired with the reason of failure. * @param section: section of packet where this rrset comes from. * @param qstate: qstate with region. + * @param vq: validator qstate with attempt counts. * @param verified: if not NULL the number of RRSIG validations is returned. * @param reasonbuf: buffer to use for fail reason string print. * @param reasonlen: length of reasonbuf. @@ -273,8 +275,9 @@ enum sec_status dnskeyset_verify_rrset(s struct val_env* ve, struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey, uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus, - sldns_pkt_section section, struct module_qstate* qstate, int* verified, - char* reasonbuf, size_t reasonlen); + sldns_pkt_section section, struct module_qstate* qstate, + struct val_qstate* vq, int* verified, char* reasonbuf, + size_t reasonlen); /** * verify rrset against one specific dnskey (from rrset) @@ -287,13 +290,16 @@ enum sec_status dnskeyset_verify_rrset(s * @param reason_bogus: EDE (RFC8914) code paired with the reason of failure. * @param section: section of packet where this rrset comes from. * @param qstate: qstate with region. + * @param vq: validator qstate with attempt counts. + * @param num_tagmatches: incremented to keep track of tag matches. * @return secure if *this* key signs any of the signatures on rrset. * unchecked on error or and bogus on bad signature. */ enum sec_status dnskey_verify_rrset(struct module_env* env, struct val_env* ve, struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* dnskey, size_t dnskey_idx, char** reason, sldns_ede_code *reason_bogus, - sldns_pkt_section section, struct module_qstate* qstate); + sldns_pkt_section section, struct module_qstate* qstate, + struct val_qstate* vq, size_t* num_tagmatches); /** * verify rrset, with specific dnskey(from set), for a specific rrsig @@ -311,7 +317,7 @@ enum sec_status dnskey_verify_rrset(stru * pass false at start. pass old value only for same rrset and same * signature (but perhaps different key) for reuse. * @param reason: if bogus, a string returned, fixed or alloced in scratch. - * @param reason_bogus: EDE (8914) code paired with the reason of failure. + * @param reason_bogus: EDE (RFC8914) code paired with the reason of failure. * @param section: section of packet where this rrset comes from. * @param qstate: qstate with region. * @return secure if this key signs this signature. unchecked on error or Index: sbin/unwind/libunbound/validator/val_utils.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/validator/val_utils.c,v diff -u -p -r1.10 val_utils.c --- sbin/unwind/libunbound/validator/val_utils.c 5 Sep 2024 08:22:48 -0000 1.10 +++ sbin/unwind/libunbound/validator/val_utils.c 21 Sep 2026 16:28:30 -0000 @@ -157,7 +157,7 @@ val_classify_response(uint16_t query_fla } /** Get signer name from RRSIG */ -static void +void rrsig_get_signer(uint8_t* data, size_t len, uint8_t** sname, size_t* slen) { /* RRSIG rdata is not allowed to be compressed, it is stored @@ -406,7 +406,8 @@ val_verify_rrset(struct module_env* env, struct ub_packed_rrset_key* rrset, struct ub_packed_rrset_key* keys, uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus, sldns_pkt_section section, struct module_qstate* qstate, - int *verified, char* reasonbuf, size_t reasonlen) + struct val_qstate* vq, int *verified, char* reasonbuf, + size_t reasonlen) { enum sec_status sec; struct packed_rrset_data* d = (struct packed_rrset_data*)rrset-> @@ -431,7 +432,8 @@ val_verify_rrset(struct module_env* env, log_nametypeclass(VERB_ALGO, "verify rrset", rrset->rk.dname, ntohs(rrset->rk.type), ntohs(rrset->rk.rrset_class)); sec = dnskeyset_verify_rrset(env, ve, rrset, keys, sigalg, reason, - reason_bogus, section, qstate, verified, reasonbuf, reasonlen); + reason_bogus, section, qstate, vq, verified, reasonbuf, + reasonlen); verbose(VERB_ALGO, "verify result: %s", sec_status_to_string(sec)); regional_free_all(env->scratch); @@ -439,10 +441,15 @@ val_verify_rrset(struct module_env* env, * only improves security status * and bogus is set only once, even if we rechecked the status */ if(sec > d->security) { + int wc_expanded = 0; d->security = sec; - if(sec == sec_status_secure) + if(sec == sec_status_secure) { + uint8_t* wc = NULL; + size_t wclen = 0; d->trust = rrset_trust_validated; - else if(sec == sec_status_bogus) { + if(val_rrset_wildcard(rrset, &wc, &wclen) && wc) + wc_expanded = 1; + } else if(sec == sec_status_bogus) { size_t i; /* update ttl for rrset to fixed value. */ d->ttl = ve->bogus_ttl; @@ -455,7 +462,11 @@ val_verify_rrset(struct module_env* env, lock_basic_unlock(&ve->bogus_lock); } /* if status updated - store in cache for reuse */ - rrset_update_sec_status(env->rrset_cache, rrset, *env->now); + /* For a wildcard rrset, that is secure, do not store this + * into the cache, because it changes proofs around the + * item. */ + if(!wc_expanded) + rrset_update_sec_status(env->rrset_cache, rrset, *env->now); } return sec; @@ -466,7 +477,8 @@ val_verify_rrset_entry(struct module_env struct ub_packed_rrset_key* rrset, struct key_entry_key* kkey, char** reason, sldns_ede_code *reason_bogus, sldns_pkt_section section, struct module_qstate* qstate, - int* verified, char* reasonbuf, size_t reasonlen) + struct val_qstate* vq, int* verified, char* reasonbuf, + size_t reasonlen) { /* temporary dnskey rrset-key */ struct ub_packed_rrset_key dnskey; @@ -480,7 +492,8 @@ val_verify_rrset_entry(struct module_env dnskey.entry.key = &dnskey; dnskey.entry.data = kd->rrset_data; sec = val_verify_rrset(env, ve, rrset, &dnskey, kd->algo, reason, - reason_bogus, section, qstate, verified, reasonbuf, reasonlen); + reason_bogus, section, qstate, vq, verified, reasonbuf, + reasonlen); return sec; } @@ -490,13 +503,20 @@ verify_dnskeys_with_ds_rr(struct module_ struct ub_packed_rrset_key* dnskey_rrset, struct ub_packed_rrset_key* ds_rrset, size_t ds_idx, char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate, - int *nonechecked, char* reasonbuf, size_t reasonlen) + struct val_qstate* vq, int *nonechecked, char* reasonbuf, + size_t reasonlen, size_t* num_tagmatches, + size_t* num_tagmatches_dnskeysig) { enum sec_status sec = sec_status_bogus; size_t i, num, numchecked = 0, numhashok = 0, numsizesupp = 0; num = rrset_get_count(dnskey_rrset); *nonechecked = 0; for(i=0; i MAX_TAG_MATCHES) { + verbose(VERB_ALGO, "DS match attempt reached " + "MAX_TAG_MATCHES (%d); bogus", MAX_TAG_MATCHES); + return sec_status_bogus; + } /* Skip DNSKEYs that don't match the basic criteria. */ if(ds_get_key_algo(ds_rrset, ds_idx) != dnskey_get_algo(dnskey_rrset, i) @@ -509,6 +529,15 @@ verify_dnskeys_with_ds_rr(struct module_ ds_get_key_algo(ds_rrset, ds_idx), ds_get_keytag(ds_rrset, ds_idx)); + if(vq && vq->num_hash_attempts++ > env->cfg->val_hash_attempts) { + *reason = "too many hash attempts"; + if(reason_bogus) + *reason_bogus = LDNS_EDE_DNSSEC_BOGUS; + verbose(VERB_ALGO, "rrset failed to verify: too many hash attempts, " + "val-hash-attempts (%d); bogus", env->cfg->val_hash_attempts); + return sec_status_bogus; + } + /* Convert the candidate DNSKEY into a hash using the * same DS hash algorithm. */ if(!ds_digest_match_dnskey(env, dnskey_rrset, i, ds_rrset, @@ -532,8 +561,14 @@ verify_dnskeys_with_ds_rr(struct module_ /* Otherwise, we have a match! Make sure that the DNSKEY * verifies *with this key* */ + if(*num_tagmatches_dnskeysig > MAX_TAG_MATCHES) { + verbose(VERB_ALGO, "DS that matched has too many DNSKEY to RRSIG tag matches " + "MAX_TAG_MATCHES (%d); bogus", MAX_TAG_MATCHES); + return sec_status_bogus; + } sec = dnskey_verify_rrset(env, ve, dnskey_rrset, dnskey_rrset, - i, reason, reason_bogus, LDNS_SECTION_ANSWER, qstate); + i, reason, reason_bogus, LDNS_SECTION_ANSWER, qstate, + vq, num_tagmatches_dnskeysig); if(sec == sec_status_secure) { return sec; } @@ -577,14 +612,14 @@ val_verify_DNSKEY_with_DS(struct module_ struct ub_packed_rrset_key* dnskey_rrset, struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate, - char* reasonbuf, size_t reasonlen) + struct val_qstate* vq, char* reasonbuf, size_t reasonlen) { /* as long as this is false, we can consider this DS rrset to be * equivalent to no DS rrset. */ int has_useful_ds = 0, digest_algo, alg, has_algo_refusal = 0, nonechecked, has_checked_ds = 0; struct algo_needs needs; - size_t i, num; + size_t i, num, num_tagmatches = 0, num_tagmatches_dnskeysig = 0; enum sec_status sec; if(dnskey_rrset->rk.dname_len != ds_rrset->rk.dname_len || @@ -606,6 +641,13 @@ val_verify_DNSKEY_with_DS(struct module_ } num = rrset_get_count(ds_rrset); for(i=0; i MAX_TAG_MATCHES) { + verbose(VERB_ALGO, "DS verify attempt reached " + "MAX_TAG_MATCHES (%d); bogus", MAX_TAG_MATCHES); + *reason = "DS verify has too many tag matches"; + return sec_status_bogus; + } + /* Check to see if we can understand this DS. * And check it is the strongest digest */ if(!ds_digest_algo_is_supported(ds_rrset, i) || @@ -614,9 +656,16 @@ val_verify_DNSKEY_with_DS(struct module_ continue; } + if(num_tagmatches_dnskeysig > MAX_TAG_MATCHES) { + verbose(VERB_ALGO, "DS verify attempt reached " + "DNSKEY to RRSIG MAX_TAG_MATCHES (%d); bogus", MAX_TAG_MATCHES); + *reason = "DS verify has too many DNSKEY to RRSIG tag matches"; + return sec_status_bogus; + } sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset, - ds_rrset, i, reason, reason_bogus, qstate, - &nonechecked, reasonbuf, reasonlen); + ds_rrset, i, reason, reason_bogus, qstate, vq, + &nonechecked, reasonbuf, reasonlen, &num_tagmatches, + &num_tagmatches_dnskeysig); if(sec == sec_status_insecure) { /* DNSKEY too large unsupported or algo refused by * crypto lib. */ @@ -678,12 +727,12 @@ val_verify_new_DNSKEYs(struct regional* struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset, struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate, - char* reasonbuf, size_t reasonlen) + struct val_qstate* vq, char* reasonbuf, size_t reasonlen) { uint8_t sigalg[ALGO_NEEDS_MAX+1]; enum sec_status sec = val_verify_DNSKEY_with_DS(env, ve, dnskey_rrset, ds_rrset, downprot?sigalg:NULL, reason, - reason_bogus, qstate, reasonbuf, reasonlen); + reason_bogus, qstate, vq, reasonbuf, reasonlen); if(sec == sec_status_secure) { return key_entry_create_rrset(region, @@ -709,14 +758,14 @@ val_verify_DNSKEY_with_TA(struct module_ struct ub_packed_rrset_key* ta_ds, struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate, - char* reasonbuf, size_t reasonlen) + struct val_qstate* vq, char* reasonbuf, size_t reasonlen) { /* as long as this is false, we can consider this anchor to be * equivalent to no anchor. */ int has_useful_ta = 0, digest_algo = 0, alg, has_algo_refusal = 0, nonechecked, has_checked_ds = 0; struct algo_needs needs; - size_t i, num; + size_t i, num, num_tagmatches = 0, num_tagmatches_dnskeysig = 0; enum sec_status sec; if(ta_ds && (dnskey_rrset->rk.dname_len != ta_ds->rk.dname_len || @@ -752,6 +801,15 @@ val_verify_DNSKEY_with_TA(struct module_ if(ta_ds) { num = rrset_get_count(ta_ds); for(i=0; i MAX_TAG_MATCHES) { + verbose(VERB_ALGO, "anchor DS verify attempt reached " + "MAX_TAG_MATCHES (%d); bogus", MAX_TAG_MATCHES); + *reason = "anchor DS verify has too many tag matches"; + if(reason_bogus) + *reason_bogus = LDNS_EDE_DNSSEC_BOGUS; + return sec_status_bogus; + } + /* Check to see if we can understand this DS. * And check it is the strongest digest */ if(!ds_digest_algo_is_supported(ta_ds, i) || @@ -759,9 +817,18 @@ val_verify_DNSKEY_with_TA(struct module_ ds_get_digest_algo(ta_ds, i) != digest_algo) continue; + if(num_tagmatches_dnskeysig > MAX_TAG_MATCHES) { + verbose(VERB_ALGO, "anchor DS verify has too many DNSKEY to RRSIG tag matches " + "MAX_TAG_MATCHES (%d); bogus", MAX_TAG_MATCHES); + *reason = "anchor DS verify has too many DNSKEY to RRSIG tag matches"; + if(reason_bogus) + *reason_bogus = LDNS_EDE_DNSSEC_BOGUS; + return sec_status_bogus; + } sec = verify_dnskeys_with_ds_rr(env, ve, dnskey_rrset, - ta_ds, i, reason, reason_bogus, qstate, &nonechecked, - reasonbuf, reasonlen); + ta_ds, i, reason, reason_bogus, qstate, vq, + &nonechecked, reasonbuf, reasonlen, &num_tagmatches, + &num_tagmatches_dnskeysig); if(sec == sec_status_insecure) { has_algo_refusal = 1; continue; @@ -804,8 +871,16 @@ val_verify_DNSKEY_with_TA(struct module_ /* we saw a useful TA */ has_useful_ta = 1; + if(num_tagmatches_dnskeysig > MAX_TAG_MATCHES) { + verbose(VERB_ALGO, "anchor DS that matched has too many DNSKEY to RRSIG tag matches " + "MAX_TAG_MATCHES (%d); bogus", MAX_TAG_MATCHES); + *reason = "anchor DS that matched has too many DNSKEY to RRSIG tag matches"; + if(reason_bogus) + *reason_bogus = LDNS_EDE_DNSSEC_BOGUS; + return sec_status_bogus; + } sec = dnskey_verify_rrset(env, ve, dnskey_rrset, - ta_dnskey, i, reason, reason_bogus, LDNS_SECTION_ANSWER, qstate); + ta_dnskey, i, reason, reason_bogus, LDNS_SECTION_ANSWER, qstate, vq, &num_tagmatches_dnskeysig); if(sec == sec_status_secure) { if(!sigalg || algo_needs_set_secure(&needs, (uint8_t)dnskey_get_algo(ta_dnskey, i))) { @@ -853,12 +928,13 @@ val_verify_new_DNSKEYs_with_ta(struct re struct ub_packed_rrset_key* ta_ds_rrset, struct ub_packed_rrset_key* ta_dnskey_rrset, int downprot, char** reason, sldns_ede_code *reason_bogus, - struct module_qstate* qstate, char* reasonbuf, size_t reasonlen) + struct module_qstate* qstate, struct val_qstate* vq, char* reasonbuf, + size_t reasonlen) { uint8_t sigalg[ALGO_NEEDS_MAX+1]; enum sec_status sec = val_verify_DNSKEY_with_TA(env, ve, dnskey_rrset, ta_ds_rrset, ta_dnskey_rrset, - downprot?sigalg:NULL, reason, reason_bogus, qstate, + downprot?sigalg:NULL, reason, reason_bogus, qstate, vq, reasonbuf, reasonlen); if(sec == sec_status_secure) { @@ -1043,7 +1119,7 @@ val_fill_reply(struct reply_info* chase, chase->rrsets[chase->an_numrrsets++] = orig->rrsets[j]; chase->rrsets[chase->an_numrrsets++] = orig->rrsets[i]; } - } + } /* AUTHORITY section */ for(i = (skip > orig->an_numrrsets)?skip:orig->an_numrrsets; ian_numrrsets+orig->ns_numrrsets; @@ -1066,10 +1142,10 @@ val_fill_reply(struct reply_info* chase, if(query_dname_compare(name, orig->rrsets[i]->rk.dname) == 0) chase->rrsets[chase->an_numrrsets - +orig->ns_numrrsets+chase->ar_numrrsets++] + +chase->ns_numrrsets+chase->ar_numrrsets++] = orig->rrsets[i]; } else if(rrset_has_signer(orig->rrsets[i], name, len)) { - chase->rrsets[chase->an_numrrsets+orig->ns_numrrsets+ + chase->rrsets[chase->an_numrrsets+chase->ns_numrrsets+ chase->ar_numrrsets++] = orig->rrsets[i]; } } @@ -1077,6 +1153,23 @@ val_fill_reply(struct reply_info* chase, chase->ar_numrrsets; } +void val_reply_remove_answers(struct reply_info* rep, size_t index, + size_t count) +{ + log_assert(index < rep->rrset_count); + log_assert(index < rep->an_numrrsets); + if(count == 0) + return; /* nothing to do */ + log_assert(index+(count-1) < rep->rrset_count); + log_assert(index+(count-1) < rep->an_numrrsets); + if(rep->rrset_count - (count-1) - index - 1 > 0) + memmove(rep->rrsets+index, rep->rrsets+index+(count-1)+1, + sizeof(struct ub_packed_rrset_key*)* + (rep->rrset_count - (count-1) - index - 1)); + rep->an_numrrsets -= count; + rep->rrset_count -= count; +} + void val_reply_remove_auth(struct reply_info* rep, size_t index) { log_assert(index < rep->rrset_count); @@ -1310,15 +1403,18 @@ val_find_DS(struct module_env* env, uint /* DS rrset exists. Return it to the validator immediately*/ struct ub_packed_rrset_key* copy = packed_rrset_copy_region( rrset, region, *env->now); + struct packed_rrset_data* d; lock_rw_unlock(&rrset->entry.lock); if(!copy) return NULL; + d = (struct packed_rrset_data*)copy->entry.data; msg = dns_msg_create(nm, nmlen, LDNS_RR_TYPE_DS, c, region, 1); if(!msg) return NULL; msg->rep->rrsets[0] = copy; msg->rep->rrset_count++; msg->rep->an_numrrsets++; + UPDATE_TTL_FROM_RRSET(msg->rep->ttl, d->ttl); return msg; } /* lookup in rrset and negative cache for NSEC/NSEC3 */ @@ -1331,4 +1427,44 @@ val_find_DS(struct module_env* env, uint msg = val_neg_getmsg(env->neg_cache, &qinfo, region, env->rrset_cache, env->scratch_buffer, *env->now, 0, topname, env->cfg); return msg; +} + +int derive_cname_from_dname(struct ub_packed_rrset_key* cname, + struct ub_packed_rrset_key* dname, uint8_t* out, size_t outlen) +{ + size_t prefix_len; + uint8_t* dname_target = NULL; + size_t dname_target_len = 0; + if(!dname_strict_subdomain_c(cname->rk.dname, dname->rk.dname)) + return 0; /* Invalid: CNAME owner must be subdomain */ + get_cname_target(dname, &dname_target, &dname_target_len); + if(!dname_target || !dname_target_len) + return 0; /* DNAME malformed */ + if(cname->rk.dname_len < dname->rk.dname_len) + return 0; /* Not possible, due to subdomain, but check */ + if(cname->rk.dname_len == 0) + return 0; /* Not possible, but check */ + prefix_len = cname->rk.dname_len - dname->rk.dname_len; + if(prefix_len + dname_target_len > outlen) + return 0; /* Buffer too small */ + memmove(out, cname->rk.dname, prefix_len); + memmove(out+prefix_len, dname_target, dname_target_len); + return 1; +} + +int nsec_nextowner_subdomain(struct ub_packed_rrset_key* rrset, uint8_t* name) +{ + struct packed_rrset_data* d; + uint8_t* next; + size_t nextlen; + if(ntohs(rrset->rk.type) != LDNS_RR_TYPE_NSEC) + return 0; + d = (struct packed_rrset_data*)rrset->entry.data; + if(!d || d->count == 0) + return 0; + next = d->rr_data[0]+2; + nextlen = dname_valid(next, d->rr_len[0]-2); + if(nextlen == 0) + return 0; /* malformed */ + return dname_subdomain_c(next, name); } Index: sbin/unwind/libunbound/validator/val_utils.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/validator/val_utils.h,v diff -u -p -r1.4 val_utils.h --- sbin/unwind/libunbound/validator/val_utils.h 5 Sep 2024 08:22:48 -0000 1.4 +++ sbin/unwind/libunbound/validator/val_utils.h 21 Sep 2026 16:28:30 -0000 @@ -55,6 +55,11 @@ struct regional; struct val_anchors; struct rrset_cache; struct sock_list; +struct val_qstate; + +/** Maximum number of matches with key tag and algorithm, for DNSKEY to + * RRSIG and DS to DNSKEY. Since the number is O(N*N), there is a limit. */ +#define MAX_TAG_MATCHES 256 /** * Response classifications for the validator. The different types of proofs. @@ -124,6 +129,7 @@ void val_find_signer(enum val_classifica * @param reason_bogus: EDE (RFC8914) code paired with the reason of failure. * @param section: section of packet where this rrset comes from. * @param qstate: qstate with region. + * @param vq: validator qstate with attempt counts. * @param verified: if not NULL, the number of RRSIG validations is returned. * @param reasonbuf: buffer to use for fail reason string print. * @param reasonlen: length of reasonbuf. @@ -133,7 +139,8 @@ enum sec_status val_verify_rrset_entry(s struct val_env* ve, struct ub_packed_rrset_key* rrset, struct key_entry_key* kkey, char** reason, sldns_ede_code *reason_bogus, sldns_pkt_section section, struct module_qstate* qstate, - int* verified, char* reasonbuf, size_t reasonlen); + struct val_qstate* vq, int* verified, char* reasonbuf, + size_t reasonlen); /** * Verify DNSKEYs with DS rrset. Like val_verify_new_DNSKEYs but @@ -148,6 +155,7 @@ enum sec_status val_verify_rrset_entry(s * @param reason: reason of failure. Fixed string or alloced in scratch. * @param reason_bogus: EDE (RFC8914) code paired with the reason of failure. * @param qstate: qstate with region. + * @param vq: validator qstate with attempt counts. * @param reasonbuf: buffer to use for fail reason string print. * @param reasonlen: length of reasonbuf. * @return: sec_status_secure if a DS matches. @@ -158,7 +166,7 @@ enum sec_status val_verify_DNSKEY_with_D struct val_env* ve, struct ub_packed_rrset_key* dnskey_rrset, struct ub_packed_rrset_key* ds_rrset, uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate, - char* reasonbuf, size_t reasonlen); + struct val_qstate* vq, char* reasonbuf, size_t reasonlen); /** * Verify DNSKEYs with DS and DNSKEY rrset. Like val_verify_DNSKEY_with_DS @@ -172,8 +180,9 @@ enum sec_status val_verify_DNSKEY_with_D * algorithm is enough. The list of signalled algorithms is returned, * must have enough space for ALGO_NEEDS_MAX+1. * @param reason: reason of failure. Fixed string or alloced in scratch. -* @param reason_bogus: EDE (RFC8914) code paired with the reason of failure. + * @param reason_bogus: EDE (RFC8914) code paired with the reason of failure. * @param qstate: qstate with region. + * @param vq: validator qstate with attempt counts. * @param reasonbuf: buffer to use for fail reason string print. * @param reasonlen: length of reasonbuf. * @return: sec_status_secure if a DS matches. @@ -185,7 +194,7 @@ enum sec_status val_verify_DNSKEY_with_T struct ub_packed_rrset_key* ta_ds, struct ub_packed_rrset_key* ta_dnskey, uint8_t* sigalg, char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate, - char* reasonbuf, size_t reasonlen); + struct val_qstate* vq, char* reasonbuf, size_t reasonlen); /** * Verify new DNSKEYs with DS rrset. The DS contains hash values that should @@ -202,6 +211,7 @@ enum sec_status val_verify_DNSKEY_with_T * @param reason: reason of failure. Fixed string or alloced in scratch. * @param reason_bogus: EDE (RFC8914) code paired with the reason of failure. * @param qstate: qstate with region. + * @param vq: validator qstate with attempt counts. * @param reasonbuf: buffer to use for fail reason string print. * @param reasonlen: length of reasonbuf. * @return a KeyEntry. This will either contain the now trusted @@ -219,7 +229,7 @@ struct key_entry_key* val_verify_new_DNS struct ub_packed_rrset_key* dnskey_rrset, struct ub_packed_rrset_key* ds_rrset, int downprot, char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate, - char* reasonbuf, size_t reasonlen); + struct val_qstate* vq, char* reasonbuf, size_t reasonlen); /** * Verify rrset with trust anchor: DS and DNSKEY rrset. @@ -235,6 +245,7 @@ struct key_entry_key* val_verify_new_DNS * @param reason: reason of failure. Fixed string or alloced in scratch. * @param reason_bogus: EDE (RFC8914) code paired with the reason of failure. * @param qstate: qstate with region. + * @param vq: validator qstate with attempt counts. * @param reasonbuf: buffer to use for fail reason string print. * @param reasonlen: length of reasonbuf. * @return a KeyEntry. This will either contain the now trusted @@ -253,7 +264,7 @@ struct key_entry_key* val_verify_new_DNS struct ub_packed_rrset_key* ta_ds_rrset, struct ub_packed_rrset_key* ta_dnskey_rrset, int downprot, char** reason, sldns_ede_code *reason_bogus, struct module_qstate* qstate, - char* reasonbuf, size_t reasonlen); + struct val_qstate* vq, char* reasonbuf, size_t reasonlen); /** * Determine if DS rrset is usable for validator or not. @@ -315,6 +326,16 @@ void val_fill_reply(struct reply_info* c size_t cname_skip, uint8_t* name, size_t len, uint8_t* signer); /** + * Remove rrsets with index .. index+count from reply, from the answer section. + * @param rep: reply to remove it from. + * @param index: rrset to remove, must be in the answer section. + * @param count: number of rrsets to remove, starting from the index. + * with count=1, it removes only the index rrset. + */ +void val_reply_remove_answers(struct reply_info* rep, size_t index, + size_t count); + +/** * Remove rrset with index from reply, from the authority section. * @param rep: reply to remove it from. * @param index: rrset to remove, must be in the authority section. @@ -426,5 +447,23 @@ int val_favorite_ds_algo(struct ub_packe */ struct dns_msg* val_find_DS(struct module_env* env, uint8_t* nm, size_t nmlen, uint16_t c, struct regional* region, uint8_t* topname); + +/** + * Derive expected CNAME target from DNAME substitution per RFC 6672 s3.1 + * @param cname: CNAME RRset, (e.g., b.d.a005.test CNAME 'some cname target') + * @param dname: DNAME RRset, (e.g., d.a005.test DNAME tgt.a005.test) + * @param out: Output buffer for expected CNAME target + * @param outlen: Output buffer size + * @return: 1 on success, 0 on error + */ +int derive_cname_from_dname(struct ub_packed_rrset_key* cname, + struct ub_packed_rrset_key* dname, uint8_t* out, size_t outlen); + +/** Get signer name from RRSIG, sname is NULL if malformed. */ +void rrsig_get_signer(uint8_t* data, size_t len, uint8_t** sname, + size_t* slen); + +/** See if the NSEC nextowner name is a subdomain of the name. */ +int nsec_nextowner_subdomain(struct ub_packed_rrset_key* rrset, uint8_t* name); #endif /* VALIDATOR_VAL_UTILS_H */ Index: sbin/unwind/libunbound/validator/validator.c =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/validator/validator.c,v diff -u -p -r1.17 validator.c --- sbin/unwind/libunbound/validator/validator.c 29 Sep 2025 14:53:38 -0000 1.17 +++ sbin/unwind/libunbound/validator/validator.c 21 Sep 2026 16:28:30 -0000 @@ -68,6 +68,9 @@ #define MAX_VALIDATE_AT_ONCE 8 /** Max number of validation suspends allowed, error out otherwise. */ #define MAX_VALIDATION_SUSPENDS 16 +/** Max answer RRsets for qtype ANY that are validated. The lists is + * shortened to fit this limit. */ +#define MAX_RRSETS_ANY_VALIDATED 24 /* forward decl for cache response and normal super inform calls of a DS */ static void process_ds_response(struct module_qstate* qstate, @@ -347,13 +350,17 @@ static void val_restart(struct val_qstate* vq) { struct comm_timer* temp_timer; - int restart_count; + int restart_count, num_validation_attempts, num_hash_attempts; if(!vq) return; temp_timer = vq->suspend_timer; restart_count = vq->restart_count+1; + num_validation_attempts = vq->num_validation_attempts; + num_hash_attempts = vq->num_hash_attempts; memset(vq, 0, sizeof(*vq)); vq->suspend_timer = temp_timer; vq->restart_count = restart_count; + vq->num_validation_attempts = num_validation_attempts; + vq->num_hash_attempts = num_hash_attempts; vq->state = VAL_INIT_STATE; } @@ -452,6 +459,24 @@ already_validated(struct dns_msg* ret_ms return 0; } +/** If it is possible to restart the validation state */ +static int +val_can_restart(struct module_qstate* qstate, struct val_qstate* vq, + struct val_env* ve) +{ + /* For validation failures that are limits exceeded on the amount + * of work that the DNSSEC validator is willing to do, the restart + * is not allowed. A restart would increase the amount of effort + * spent even further. */ + if(vq->restart_count < ve->max_restart && + vq->num_validation_attempts <= qstate->env->cfg->val_validation_attempts && + vq->num_hash_attempts <= qstate->env->cfg->val_hash_attempts && + !vq->num_nsec_attempts_exceeded) + return 1; + (void)qstate; + return 0; +} + /** * Generate a request for DNS data. * @@ -496,7 +521,7 @@ generate_request(struct module_qstate* q struct mesh_state* sub = NULL; fptr_ok(fptr_whitelist_modenv_add_sub( qstate->env->add_sub)); - if(!(*qstate->env->add_sub)(qstate, &ask, + if(!(*qstate->env->add_sub)(qstate, &ask, NULL, (uint16_t)(BIT_RD|flags), 0, valrec, newq, &sub)){ log_err("Could not generate request: out of memory"); return 0; @@ -505,7 +530,7 @@ generate_request(struct module_qstate* q else { fptr_ok(fptr_whitelist_modenv_attach_sub( qstate->env->attach_sub)); - if(!(*qstate->env->attach_sub)(qstate, &ask, + if(!(*qstate->env->attach_sub)(qstate, &ask, NULL, (uint16_t)(BIT_RD|flags), 0, valrec, newq)){ log_err("Could not generate request: out of memory"); return 0; @@ -517,6 +542,14 @@ generate_request(struct module_qstate* q /* add our blacklist to the query blacklist */ sock_list_merge(&(*newq)->blacklist, (*newq)->region, vq->chain_blacklist); + /* start its global quota counter where this one is. */ + if(qstate->global_quota_reached > + (*newq)->global_quota_reached) { + (*newq)->global_quota_started = + qstate->global_quota_reached; + (*newq)->global_quota_reached = + qstate->global_quota_reached; + } } qstate->ext_state[id] = module_wait_subquery; return 1; @@ -710,6 +743,37 @@ validate_msg_signatures(struct module_qs ((struct packed_rrset_data*)chase_reply->rrsets[i-1]->entry.data)->security == sec_status_secure && dname_strict_subdomain_c(s->rk.dname, chase_reply->rrsets[i-1]->rk.dname) ) { + /* Check that the CNAME target matches the DNAME + * derivation. Zone changes during the redirection + * lookups or looped DNAMEs can have such a CNAME. */ + uint8_t expected_target[LDNS_MAX_DOMAINLEN]; + uint8_t* cname_target = NULL; + size_t cname_target_len = 0; + get_cname_target(s, &cname_target, &cname_target_len); + if(!cname_target || + !derive_cname_from_dname(s, /* CNAME RRset */ + chase_reply->rrsets[i-1], /* DNAME RRset */ + expected_target, /* Output buffer */ + sizeof(expected_target))) { + verbose(VERB_ALGO, "DNAME CNAME derivation failed"); + errinf_ede(qstate, "DNAME CNAME derivation failed", reason_bogus); + errinf_origin(qstate, qstate->reply_origin); + chase_reply->security = sec_status_bogus; + update_reason_bogus(chase_reply, reason_bogus); + return 0; + } + if(query_dname_compare(cname_target, expected_target) != 0) { + verbose(VERB_ALGO, "CNAME target mismatch: not synthesized from DNAME"); + errinf_ede(qstate, "CNAME target mismatch: not synthesized from DNAME", reason_bogus); + errinf_dname(qstate, ", for", s->rk.dname); + errinf_dname(qstate, "CNAME", cname_target); + errinf(qstate, ","); + errinf_origin(qstate, qstate->reply_origin); + chase_reply->security = sec_status_bogus; + update_reason_bogus(chase_reply, reason_bogus); + return 0; + } + /* CNAME was synthesized by our own iterator */ /* since the DNAME verified, mark the CNAME as secure */ ((struct packed_rrset_data*)s->entry.data)->security = @@ -721,8 +785,8 @@ validate_msg_signatures(struct module_qs /* Verify the answer rrset */ sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason, - &reason_bogus, LDNS_SECTION_ANSWER, qstate, &verified, - reasonbuf, sizeof(reasonbuf)); + &reason_bogus, LDNS_SECTION_ANSWER, qstate, vq, + &verified, reasonbuf, sizeof(reasonbuf)); /* If the (answer) rrset failed to validate, then this * message is BAD. */ if(sec != sec_status_secure) { @@ -766,7 +830,7 @@ validate_msg_signatures(struct module_qs continue; s = chase_reply->rrsets[i]; sec = val_verify_rrset_entry(env, ve, s, key_entry, &reason, - &reason_bogus, LDNS_SECTION_AUTHORITY, qstate, + &reason_bogus, LDNS_SECTION_AUTHORITY, qstate, vq, &verified, reasonbuf, sizeof(reasonbuf)); /* If anything in the authority section fails to be secure, * we have a bad message. */ @@ -813,7 +877,7 @@ validate_msg_signatures(struct module_qs if(sname && query_dname_compare(sname, key_entry->name)==0) (void)val_verify_rrset_entry(env, ve, s, key_entry, &reason, NULL, LDNS_SECTION_ADDITIONAL, qstate, - &verified, reasonbuf, sizeof(reasonbuf)); + vq, &verified, reasonbuf, sizeof(reasonbuf)); /* the additional section can fail to be secure, * it is optional, check signature in case we need * to clean the additional section later. */ @@ -882,10 +946,10 @@ validate_suspend_setup_timer(struct modu slack += 2; else if(qstate->env->mesh->all.count >= qstate->env->mesh->max_reply_states/4) slack += 1; - if(vq->suspend_count > 3) - slack += 3; - else if(vq->suspend_count > 0) - slack += vq->suspend_count; + /* One step of back-off after the first suspend so a single bad + * message still yields, but does not grow exponentially on its own. */ + if(vq->suspend_count > 0) + slack += 1; if(slack != 0 && slack <= 12 /* No numeric overflow. */) { usec = usec << slack; } @@ -986,6 +1050,29 @@ remove_spurious_authority(struct reply_i } /** + * Cap the number of answer RRsets for validation of type ANY. + * This limits the number of RRSIG validations performed. + * It is allowed to return a subset of available RRsets when processing + * ANY query. + * @param chase_reply: the chased reply, shorten if if too long. + * @param orig_reply: original reply, remove the records here as well, + * so it can be marked as DNSSEC valid. + * @param skip: the number of rrsets skipped in the answer section due to + * CNAME chain that is followed. + * @param max_rrsets: the number allowed. + */ +static void +shorten_answer_any(struct reply_info* chase_reply, + struct reply_info* orig_reply, size_t skip, size_t max_rrsets) +{ + if(chase_reply->an_numrrsets > max_rrsets) { + size_t to_rem = chase_reply->an_numrrsets - max_rrsets; + val_reply_remove_answers(chase_reply, max_rrsets, to_rem); + val_reply_remove_answers(orig_reply, skip+max_rrsets, to_rem); + } +} + +/** * Given a "positive" response -- a response that contains an answer to the * question, and no CNAME chain, validate this response. * @@ -1012,7 +1099,14 @@ validate_positive_response(struct module uint8_t* wc = NULL; size_t wl; int wc_cached = 0; + int wc_to_cache = 0; + uint8_t* cache_wc = NULL; + size_t cache_wl = 0; + struct ub_packed_rrset_key* cache_s = NULL; int wc_NSEC_ok = 0; + /* This is used to update the RRset cache, with the combination + * of the dname expansion and this wildcard, for security status. */ + struct ub_packed_rrset_key* wc_rrset = NULL; int nsec3s_seen = 0; size_t i; struct ub_packed_rrset_key* s; @@ -1031,14 +1125,20 @@ validate_positive_response(struct module ntohs(s->rk.type), ntohs(s->rk.rrset_class)); chase_reply->security = sec_status_bogus; update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS); + if(wc_rrset) + ((struct packed_rrset_data*)wc_rrset-> + entry.data)->security = sec_status_bogus; return; } if(wc && !wc_cached && env->cfg->aggressive_nsec) { - rrset_cache_update_wildcard(env->rrset_cache, s, wc, wl, - env->alloc, *env->now); + /* Postpone cache adjust until proof has succeeded. */ + wc_to_cache = 1; + cache_wc = wc; + cache_wl = wl; + cache_s = s; wc_cached = 1; } - + if(wc) wc_rrset = s; } /* validate the AUTHORITY section as well - this will generally be @@ -1095,8 +1195,15 @@ validate_positive_response(struct module "did not exist"); chase_reply->security = sec_status_bogus; update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS); + if(wc_rrset) + ((struct packed_rrset_data*)wc_rrset-> + entry.data)->security = sec_status_bogus; return; } + if(wc_to_cache) { + rrset_cache_update_wildcard(env->rrset_cache, cache_s, + cache_wc, cache_wl, env->alloc, *env->now); + } verbose(VERB_ALGO, "Successfully validated positive response"); chase_reply->security = sec_status_secure; @@ -1348,16 +1455,20 @@ validate_nameerror_response(struct modul * trusted DNSKEY rrset that signs this response must already have been * completed. * + * @param env: module env. * @param chase_reply: answer to validate. */ static void -validate_referral_response(struct reply_info* chase_reply) +validate_referral_response(struct module_env* env, struct reply_info* chase_reply) { - size_t i; + size_t i, count; enum sec_status s; /* message security equals lowest rrset security */ chase_reply->security = sec_status_secure; - for(i=0; irrset_count; i++) { + if(env->cfg->val_clean_additional) + count = chase_reply->rrset_count; + else count = chase_reply->an_numrrsets+chase_reply->ns_numrrsets; + for(i=0; irrsets[i] ->entry.data)->security; if(s < chase_reply->security) @@ -1496,6 +1607,16 @@ validate_any_response(struct module_env* "did not exist"); chase_reply->security = sec_status_bogus; update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS); + /* Make the expanded name and wildcard RRSIG rrsets bogus */ + for(i=0; ian_numrrsets; i++) { + uint8_t* cwc = NULL; + size_t cwl = 0; + s = chase_reply->rrsets[i]; + if(val_rrset_wildcard(s, &cwc, &cwl) && cwc) { + ((struct packed_rrset_data*)s-> + entry.data)->security = sec_status_bogus; + } + } return; } @@ -1533,6 +1654,9 @@ validate_cname_response(struct module_en uint8_t* wc = NULL; size_t wl; int wc_NSEC_ok = 0; + /* This is used to update the RRset cache, with the combination + * of the dname expansion and this wildcard, for security status. */ + struct ub_packed_rrset_key* wc_rrset = NULL; int nsec3s_seen = 0; size_t i; struct ub_packed_rrset_key* s; @@ -1553,6 +1677,7 @@ validate_cname_response(struct module_en update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS); return; } + if(wc) wc_rrset = s; /* Refuse wildcarded DNAMEs rfc 4597. * Do not follow a wildcarded DNAME because @@ -1564,6 +1689,9 @@ validate_cname_response(struct module_en ntohs(s->rk.type), ntohs(s->rk.rrset_class)); chase_reply->security = sec_status_bogus; update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS); + if(wc_rrset) + ((struct packed_rrset_data*)wc_rrset-> + entry.data)->security = sec_status_bogus; return; } @@ -1628,6 +1756,9 @@ validate_cname_response(struct module_en "did not exist"); chase_reply->security = sec_status_bogus; update_reason_bogus(chase_reply, LDNS_EDE_DNSSEC_BOGUS); + if(wc_rrset) + ((struct packed_rrset_data*)wc_rrset-> + entry.data)->security = sec_status_bogus; return; } @@ -2204,7 +2335,7 @@ processValidate(struct module_qstate* qs key_entry_get_reason_bogus(vq->key_entry)); errinf_ede(qstate, "while building chain of trust", key_entry_get_reason_bogus(vq->key_entry)); - if(vq->restart_count >= ve->max_restart) + if(!val_can_restart(qstate, vq, ve)) key_cache_insert(ve->kcache, vq->key_entry, qstate->env->cfg->val_log_level >= 2); return 1; @@ -2227,6 +2358,9 @@ processValidate(struct module_qstate* qs &vq->qchase, vq->orig_msg->rep, vq->rrset_skip); if(subtype != VAL_CLASS_REFERRAL) remove_spurious_authority(vq->chase_reply, vq->orig_msg->rep); + if(subtype == VAL_CLASS_ANY) + shorten_answer_any(vq->chase_reply, vq->orig_msg->rep, + vq->rrset_skip, MAX_RRSETS_ANY_VALIDATED); /* check signatures in the message; * answer and authority must be valid, additional is only checked. */ @@ -2349,7 +2483,7 @@ processValidate(struct module_qstate* qs case VAL_CLASS_REFERRAL: verbose(VERB_ALGO, "Validating a referral response"); - validate_referral_response(vq->chase_reply); + validate_referral_response(qstate->env, vq->chase_reply); verbose(VERB_DETAIL, "validate(referral): %s", sec_status_to_string( vq->chase_reply->security)); @@ -2423,15 +2557,17 @@ processFinished(struct module_qstate* qs } if(subtype == VAL_CLASS_REFERRAL) { - /* for a referral, move to next unchecked rrset and check it*/ - vq->rrset_skip = val_next_unchecked(vq->orig_msg->rep, - vq->rrset_skip); - if(vq->rrset_skip < vq->orig_msg->rep->rrset_count) { - /* and restart for this rrset */ - verbose(VERB_ALGO, "validator: go to next rrset"); - vq->chase_reply->security = sec_status_unchecked; - vq->state = VAL_INIT_STATE; - return 1; + if(qstate->env->cfg->val_clean_additional) { + /* for a referral, move to next unchecked rrset and check it*/ + vq->rrset_skip = val_next_unchecked(vq->orig_msg->rep, + vq->rrset_skip); + if(vq->rrset_skip < vq->orig_msg->rep->rrset_count) { + /* and restart for this rrset */ + verbose(VERB_ALGO, "validator: go to next rrset"); + vq->chase_reply->security = sec_status_unchecked; + vq->state = VAL_INIT_STATE; + return 1; + } } /* referral chase is done */ } @@ -2476,7 +2612,7 @@ processFinished(struct module_qstate* qs struct msgreply_entry* e; /* see if we can try again to fetch data */ - if(vq->restart_count < ve->max_restart) { + if(val_can_restart(qstate, vq, ve)) { verbose(VERB_ALGO, "validation failed, " "blacklist and retry to fetch data"); val_blacklist(&qstate->blacklist, qstate->region, @@ -2699,7 +2835,9 @@ val_operate(struct module_qstate* qstate if(!needs_validation(qstate, qstate->return_rcode, qstate->return_msg)) { /* no need to validate this */ - if(qstate->return_msg) + /* For valrec responses, leave at sec_status_unchecked, + * no security status has been requested for it. */ + if(qstate->return_msg && !qstate->is_valrec) qstate->return_msg->rep->security = sec_status_indeterminate; qstate->ext_state[id] = module_finished; @@ -2766,6 +2904,7 @@ val_operate(struct module_qstate* qstate * (this rrset is allocated in the wrong region, not the qstate). * @param ta: trust anchor. * @param qstate: qstate that needs key. + * @param vq: validator qstate. * @param id: module id. * @param sub_qstate: the sub query state, that is the lookup that fetched * the trust anchor data, it contains error information for the answer. @@ -2776,8 +2915,8 @@ val_operate(struct module_qstate* qstate */ static struct key_entry_key* primeResponseToKE(struct ub_packed_rrset_key* dnskey_rrset, - struct trust_anchor* ta, struct module_qstate* qstate, int id, - struct module_qstate* sub_qstate) + struct trust_anchor* ta, struct module_qstate* qstate, + struct val_qstate* vq, int id, struct module_qstate* sub_qstate) { struct val_env* ve = (struct val_env*)qstate->env->modinfo[id]; struct key_entry_key* kkey = NULL; @@ -2817,7 +2956,8 @@ primeResponseToKE(struct ub_packed_rrset /* attempt to verify with trust anchor DS and DNSKEY */ kkey = val_verify_new_DNSKEYs_with_ta(qstate->region, qstate->env, ve, dnskey_rrset, ta->ds_rrset, ta->dnskey_rrset, downprot, - &reason, &reason_bogus, qstate, reasonbuf, sizeof(reasonbuf)); + &reason, &reason_bogus, qstate, vq, reasonbuf, + sizeof(reasonbuf)); if(!kkey) { log_err("out of memory: verifying prime TA"); return NULL; @@ -2930,7 +3070,7 @@ ds_response_to_ke(struct module_qstate* * bogus, then we are done. */ sec = val_verify_rrset_entry(qstate->env, ve, ds, vq->key_entry, &reason, &reason_bogus, - LDNS_SECTION_ANSWER, qstate, &verified, reasonbuf, + LDNS_SECTION_ANSWER, qstate, vq, &verified, reasonbuf, sizeof(reasonbuf)); if(sec != sec_status_secure) { verbose(VERB_DETAIL, "DS rrset in DS response did " @@ -2981,7 +3121,7 @@ ds_response_to_ke(struct module_qstate* /* Try to prove absence of the DS with NSEC */ sec = val_nsec_prove_nodata_dsreply( qstate->env, ve, qinfo, msg->rep, vq->key_entry, - &proof_ttl, &reason, &reason_bogus, qstate, + &proof_ttl, &reason, &reason_bogus, qstate, vq, reasonbuf, sizeof(reasonbuf)); switch(sec) { case sec_status_secure: @@ -3019,7 +3159,7 @@ ds_response_to_ke(struct module_qstate* sec = nsec3_prove_nods(qstate->env, ve, msg->rep->rrsets + msg->rep->an_numrrsets, msg->rep->ns_numrrsets, qinfo, vq->key_entry, &reason, - &reason_bogus, qstate, &vq->nsec3_cache_table, + &reason_bogus, qstate, vq, &vq->nsec3_cache_table, reasonbuf, sizeof(reasonbuf)); switch(sec) { case sec_status_insecure: @@ -3087,9 +3227,65 @@ ds_response_to_ke(struct module_qstate* } sec = val_verify_rrset_entry(qstate->env, ve, cname, vq->key_entry, &reason, &reason_bogus, - LDNS_SECTION_ANSWER, qstate, &verified, reasonbuf, + LDNS_SECTION_ANSWER, qstate, vq, &verified, reasonbuf, sizeof(reasonbuf)); if(sec == sec_status_secure) { + /* Check for wildcard expansion */ + uint8_t* wc = NULL; + size_t wl = 0; + + if(!val_rrset_wildcard(cname, &wc, &wl)) { + verbose(VERB_ALGO, "CNAME has inconsistent wildcard signatures"); + reason = "wildcard CNAME inconsistent signatures"; + errinf_ede(qstate, reason, reason_bogus); + goto return_bogus; + } + + if(wc != NULL) { + /* Wildcard expansion detected - require NSEC proof */ + /* So this is a wildcard CNAME response to DS. + * If the wildcard is bogus then we have bogus. + * If the wildcard is true, then there is + * not a referral point here or lower, + * that can be insecure, + * and also no DS records, here or lower. */ + /* For a valid chain, to DS, but this + * wildcard CNAME happens in a middle label, + * then that can not happen, because there is + * data under that label, and thus the wildcard + * should not expand. + * If we are going to the wildcard, that also + * does not expand the wildcard, when above it. + * So for valids lookup chains to DS, no + * wildcard CNAME is expected on middle labels. + * For lookups to an insecure point, the + * delegation is information under the label, + * and thus the wildcard does not expand. + * So, no insecure point is possible. + * Can not get a valid chain of trust, or + * to a delegation point for insecure. + * Or the wildcard, its nxdomain for the qname + * proof, is invalid, in which case this is + * a bogus reply. + * If this was a lookup where a wildcard + * expansion is genuinely expected, eg, + * a dnssec valid wildcard query, then the + * lookup should go to the right point, and + * not into the wildcard under the zone name. + * For insecure, or wildcard missing + * signatures, it would have to have found + * the DS or insecure point earlier, in the + * downwards search. + * So for missing signatures, it turns the + * missing signatures into a failure to the + * wildcard CNAME, as the reported log. + */ + verbose(VERB_ALGO, "wildcard CNAME in chain of trust means no DS can be found and it is also not a delegation point that can be insecure"); + reason = "wildcard CNAME in chain of trust means no DS found and it is also not a delegation point that can be insecure"; + errinf_ede(qstate, reason, reason_bogus); + goto return_bogus; + } + verbose(VERB_ALGO, "CNAME validated, " "proof that DS does not exist"); /* and that it is not a referral point */ @@ -3152,6 +3348,7 @@ process_ds_response(struct module_qstate uint8_t* olds = vq->empty_DS_name; int ret; *suspend = 0; + vq->num_nsec_attempts = 0; vq->empty_DS_name = NULL; if(sub_qstate && sub_qstate->rpz_applied) { verbose(VERB_ALGO, "rpz was applied to the DS lookup, " @@ -3163,6 +3360,8 @@ process_ds_response(struct module_qstate } ret = ds_response_to_ke(qstate, vq, id, rcode, msg, qinfo, &dske, sub_qstate); + /* New NSEC attempt count for next message validation. */ + vq->num_nsec_attempts = 0; if(ret != 0) { switch(ret) { case 1: @@ -3204,7 +3403,7 @@ process_ds_response(struct module_qstate vq->chain_blacklist = NULL; /* fresh blacklist for next part*/ /* Keep the forState.state on FINDKEY. */ } else if(key_entry_isbad(dske) - && vq->restart_count < ve->max_restart) { + && val_can_restart(qstate, vq, ve)) { vq->empty_DS_name = olds; val_blacklist(&vq->chain_blacklist, qstate->region, origin, 1); qstate->errinf = NULL; @@ -3254,6 +3453,7 @@ process_dnskey_response(struct module_qs char* reason = NULL; sldns_ede_code reason_bogus = LDNS_EDE_DNSSEC_BOGUS; + vq->num_nsec_attempts = 0; if(sub_qstate && sub_qstate->rpz_applied) { verbose(VERB_ALGO, "rpz was applied to the DNSKEY lookup, " "make it insecure"); @@ -3273,7 +3473,7 @@ process_dnskey_response(struct module_qs verbose(VERB_DETAIL, "Missing DNSKEY RRset in response to " "DNSKEY query."); - if(vq->restart_count < ve->max_restart) { + if(val_can_restart(qstate, vq, ve)) { val_blacklist(&vq->chain_blacklist, qstate->region, origin, 1); qstate->errinf = NULL; @@ -3310,7 +3510,9 @@ process_dnskey_response(struct module_qs downprot = qstate->env->cfg->harden_algo_downgrade; vq->key_entry = val_verify_new_DNSKEYs(qstate->region, qstate->env, ve, dnskey, vq->ds_rrset, downprot, &reason, &reason_bogus, - qstate, reasonbuf, sizeof(reasonbuf)); + qstate, vq, reasonbuf, sizeof(reasonbuf)); + /* New NSEC attempt count for next message validation. */ + vq->num_nsec_attempts = 0; if(!vq->key_entry) { log_err("out of memory in verify new DNSKEYs"); @@ -3321,7 +3523,7 @@ process_dnskey_response(struct module_qs * state. */ if(!key_entry_isgood(vq->key_entry)) { if(key_entry_isbad(vq->key_entry)) { - if(vq->restart_count < ve->max_restart) { + if(val_can_restart(qstate, vq, ve)) { val_blacklist(&vq->chain_blacklist, qstate->region, origin, 1); qstate->errinf = NULL; @@ -3373,6 +3575,7 @@ process_prime_response(struct module_qst struct trust_anchor* ta = anchor_find(qstate->env->anchors, vq->trust_anchor_name, vq->trust_anchor_labs, vq->trust_anchor_len, vq->qchase.qclass); + vq->num_nsec_attempts = 0; if(!ta) { /* trust anchor revoked, restart with less anchors */ vq->state = VAL_INIT_STATE; @@ -3391,19 +3594,23 @@ process_prime_response(struct module_qst if(ta->autr) { if(!autr_process_prime(qstate->env, ve, ta, dnskey_rrset, - qstate)) { + qstate, vq)) { + /* New NSEC attempt count for next message validation. */ + vq->num_nsec_attempts = 0; /* trust anchor revoked, restart with less anchors */ vq->state = VAL_INIT_STATE; vq->trust_anchor_name = NULL; return; } } - vq->key_entry = primeResponseToKE(dnskey_rrset, ta, qstate, id, + vq->key_entry = primeResponseToKE(dnskey_rrset, ta, qstate, vq, id, sub_qstate); lock_basic_unlock(&ta->lock); + /* New NSEC attempt count for next message validation. */ + vq->num_nsec_attempts = 0; if(vq->key_entry) { if(key_entry_isbad(vq->key_entry) - && vq->restart_count < ve->max_restart) { + && val_can_restart(qstate, vq, ve)) { val_blacklist(&vq->chain_blacklist, qstate->region, origin, 1); qstate->errinf = NULL; @@ -3446,6 +3653,11 @@ val_inform_super(struct module_qstate* q if(!vq) { verbose(VERB_ALGO, "super: has no validator state"); return; + } + /* Pick up the global quota limit from the subquery. */ + if(qstate->global_quota_reached > qstate->global_quota_started) { + super->global_quota_reached += qstate->global_quota_reached - + qstate->global_quota_started; } if(vq->wait_prime_ta) { vq->wait_prime_ta = 0; Index: sbin/unwind/libunbound/validator/validator.h =================================================================== RCS file: /cvs/src/sbin/unwind/libunbound/validator/validator.h,v diff -u -p -r1.8 validator.h --- sbin/unwind/libunbound/validator/validator.h 14 Sep 2025 15:16:53 -0000 1.8 +++ sbin/unwind/libunbound/validator/validator.h 21 Sep 2026 16:28:30 -0000 @@ -231,6 +231,19 @@ struct val_qstate { struct comm_timer* suspend_timer; /** Number of suspends */ int suspend_count; + + /** Number of DNSKEY RRSIG validation attempts. This is the number of + * cryptographic operations done for the mesh state. */ + int num_validation_attempts; + /** Number of DS hash verification attempts. This is the number of + * hash operations done for the mesh state. + * It does not count NSEC3 hashes. */ + int num_hash_attempts; + /** Number of NSEC validations. And NSEC3 too. This is reset per + * answer. */ + int num_nsec_attempts; + /** The nsec attempts have been exceeded. */ + int num_nsec_attempts_exceeded; }; /** Index: usr.sbin/unbound/README.md =================================================================== RCS file: /cvs/src/usr.sbin/unbound/README.md,v diff -u -p -r1.9 README.md --- usr.sbin/unbound/README.md 12 Apr 2024 15:45:24 -0000 1.9 +++ usr.sbin/unbound/README.md 21 Sep 2026 16:28:30 -0000 @@ -4,13 +4,13 @@ [![Packaging status](https://repology.org/badge/tiny-repos/unbound.svg)](https://repology.org/project/unbound/versions) [![Fuzzing Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/unbound.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?sort=-opened&can=1&q=proj:unbound) [![Documentation Status](https://readthedocs.org/projects/unbound/badge/?version=latest)](https://unbound.readthedocs.io/en/latest/?badge=latest) -[![Mastodon Follow](https://img.shields.io/mastodon/follow/109262826617293067?domain=https%3A%2F%2Ffosstodon.org&style=social)](https://fosstodon.org/@nlnetlabs) +[![Mastodon Follow](https://img.shields.io/mastodon/follow/114692612288811644?domain=social.nlnetlabs.nl&style=social)](https://social.nlnetlabs.nl/@nlnetlabs) Unbound is a validating, recursive, caching DNS resolver. It is designed to be fast and lean and incorporates modern features based on open standards. If you have any feedback, we would love to hear from you. Don’t hesitate to [create an issue on Github](https://github.com/NLnetLabs/unbound/issues/new) -or post a message on the [Unbound mailing list](https://lists.nlnetlabs.nl/mailman/listinfo/unbound-users). +or post a message on our [community forum](https://community.nlnetlabs.nl/). You can learn more about Unbound by reading our [documentation](https://unbound.docs.nlnetlabs.nl/). @@ -25,18 +25,21 @@ Unbound can be compiled and installed us ./configure && make && make install ``` -You can use libevent if you want. libevent is useful when using many (10000) -outgoing ports. By default max 256 ports are opened at the same time and the -builtin alternative is equally capable and a little faster. - +You can use libevent if you want. libevent is useful when using many (e.g., +10000) outgoing ports. Use the `--with-libevent` configure option to compile Unbound with libevent support. +If not, the default builtin alternative opens max 256 ports at the same time +and is equally capable and a little faster. + + ## Unbound configuration -All of Unbound's configuration options are described in the man pages, which -will be installed and are available on the Unbound -[documentation page](https://unbound.docs.nlnetlabs.nl/). +All of Unbound's configuration options are described in the `unbound.conf(5)` +man page, which will be installed and is also available on the Unbound +[documentation page](https://unbound.docs.nlnetlabs.nl/en/latest/manpages/unbound.conf.html) +for the latest version. -An example configuration file is located in +An example configuration file, with minimal documentation, is located in [doc/example.conf](https://github.com/NLnetLabs/unbound/blob/master/doc/example.conf.in). Index: usr.sbin/unbound/aclocal.m4 =================================================================== RCS file: /cvs/src/usr.sbin/unbound/aclocal.m4,v diff -u -p -r1.11 aclocal.m4 --- usr.sbin/unbound/aclocal.m4 21 Feb 2025 13:20:39 -0000 1.11 +++ usr.sbin/unbound/aclocal.m4 21 Sep 2026 16:28:30 -0000 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.16.2 -*- Autoconf -*- +# generated automatically by aclocal 1.18.1 -*- Autoconf -*- -# Copyright (C) 1996-2020 Free Software Foundation, Inc. +# Copyright (C) 1996-2025 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -14,7 +14,8 @@ m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_defun([_AM_CONFIG_MACRO_DIRS], [])m4_defun([AC_CONFIG_MACRO_DIRS], [_AM_CONFIG_MACRO_DIRS($@)])]) # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*- # -# Copyright (C) 1996-2001, 2003-2015 Free Software Foundation, Inc. +# Copyright (C) 1996-2001, 2003-2019, 2021-2024 Free Software +# Foundation, Inc. # Written by Gordon Matzigkeit, 1996 # # This file is free software; the Free Software Foundation gives @@ -22,13 +23,13 @@ m4_ifndef([AC_CONFIG_MACRO_DIRS], [m4_de # modifications, as long as this notice is preserved. m4_define([_LT_COPYING], [dnl -# Copyright (C) 2014 Free Software Foundation, Inc. +# Copyright (C) 2024 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool 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 2 of of the License, or +# the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you @@ -45,7 +46,7 @@ m4_define([_LT_COPYING], [dnl # along with this program. If not, see . ]) -# serial 58 LT_INIT +# serial 63 LT_INIT # LT_PREREQ(VERSION) @@ -73,7 +74,7 @@ esac # LT_INIT([OPTIONS]) # ------------------ AC_DEFUN([LT_INIT], -[AC_PREREQ([2.62])dnl We use AC_PATH_PROGS_FEATURE_CHECK +[AC_PREREQ([2.64])dnl We use AC_PATH_PROGS_FEATURE_CHECK AC_REQUIRE([AC_CONFIG_AUX_DIR_DEFAULT])dnl AC_BEFORE([$0], [LT_LANG])dnl AC_BEFORE([$0], [LT_OUTPUT])dnl @@ -195,6 +196,7 @@ m4_require([_LT_FILEUTILS_DEFAULTS])dnl m4_require([_LT_CHECK_SHELL_FEATURES])dnl m4_require([_LT_PATH_CONVERSION_FUNCTIONS])dnl m4_require([_LT_CMD_RELOAD])dnl +m4_require([_LT_DECL_FILECMD])dnl m4_require([_LT_CHECK_MAGIC_METHOD])dnl m4_require([_LT_CHECK_SHAREDLIB_FROM_LINKLIB])dnl m4_require([_LT_CMD_OLD_ARCHIVE])dnl @@ -233,8 +235,8 @@ esac ofile=libtool can_build_shared=yes -# All known linkers require a '.a' archive for static linking (except MSVC, -# which needs '.lib'). +# All known linkers require a '.a' archive for static linking (except MSVC and +# ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld @@ -622,7 +624,7 @@ m4_popdef([AS_MESSAGE_LOG_FD])])])# _LT_ # LT_OUTPUT # --------- # This macro allows early generation of the libtool script (before -# AC_OUTPUT is called), incase it is used in configure for compilation +# AC_OUTPUT is called), in case it is used in configure for compilation # tests. AC_DEFUN([LT_OUTPUT], [: ${CONFIG_LT=./config.lt} @@ -657,9 +659,9 @@ m4_ifset([AC_PACKAGE_NAME], [AC_PACKAGE_ m4_ifset([AC_PACKAGE_VERSION], [ AC_PACKAGE_VERSION]) configured by $[0], generated by m4_PACKAGE_STRING. -Copyright (C) 2011 Free Software Foundation, Inc. +Copyright (C) 2024 Free Software Foundation, Inc. This config.lt script is free software; the Free Software Foundation -gives unlimited permision to copy, distribute and modify it." +gives unlimited permission to copy, distribute and modify it." while test 0 != $[#] do @@ -736,7 +738,6 @@ _LT_CONFIG_SAVE_COMMANDS([ cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. @@ -786,7 +787,7 @@ _LT_EOF # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ + $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || @@ -979,6 +980,7 @@ _lt_linker_boilerplate=`cat conftest.err $RM -r conftest* ])# _LT_LINKER_BOILERPLATE + # _LT_REQUIRED_DARWIN_CHECKS # ------------------------- m4_defun_once([_LT_REQUIRED_DARWIN_CHECKS],[ @@ -1029,6 +1031,21 @@ m4_defun_once([_LT_REQUIRED_DARWIN_CHECK rm -f conftest.* fi]) + # Feature test to disable chained fixups since it is not + # compatible with '-undefined dynamic_lookup' + AC_CACHE_CHECK([for -no_fixup_chains linker flag], + [lt_cv_support_no_fixup_chains], + [ save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -Wl,-no_fixup_chains" + AC_LINK_IFELSE( + [AC_LANG_PROGRAM([],[])], + lt_cv_support_no_fixup_chains=yes, + lt_cv_support_no_fixup_chains=no + ) + LDFLAGS=$save_LDFLAGS + ] + ) + AC_CACHE_CHECK([for -exported_symbols_list linker flag], [lt_cv_ld_exported_symbols_list], [lt_cv_ld_exported_symbols_list=no @@ -1048,12 +1065,12 @@ int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&AS_MESSAGE_LOG_FD - echo "$AR cru libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD - $AR cru libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD + echo "$AR $AR_FLAGS libconftest.a conftest.o" >&AS_MESSAGE_LOG_FD + $AR $AR_FLAGS libconftest.a conftest.o 2>&AS_MESSAGE_LOG_FD echo "$RANLIB libconftest.a" >&AS_MESSAGE_LOG_FD $RANLIB libconftest.a 2>&AS_MESSAGE_LOG_FD cat > conftest.c << _LT_EOF -int main() { return 0;} +int main(void) { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&AS_MESSAGE_LOG_FD $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err @@ -1073,23 +1090,37 @@ _LT_EOF _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[[91]]*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; - 10.[[012]][[,.]]*) - _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + darwin*) + case $MACOSX_DEPLOYMENT_TARGET,$host in + 10.[[012]],*|,*powerpc*-darwin[[5-8]]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + *) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' + if test yes = "$lt_cv_support_no_fixup_chains"; then + AS_VAR_APPEND([_lt_dar_allow_undefined], [' $wl-no_fixup_chains']) + fi + ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi + _lt_dar_needs_single_mod=no + case $host_os in + rhapsody* | darwin1.*) + _lt_dar_needs_single_mod=yes ;; + darwin*) + # When targeting Mac OS X 10.4 (darwin 8) or later, + # -single_module is the default and -multi_module is unsupported. + # The toolchain on macOS 10.14 (darwin 18) and later cannot + # target any OS version that needs -single_module. + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*-darwin[[567]].*|10.[[0-3]],*-darwin[[5-9]].*|10.[[0-3]],*-darwin1[[0-7]].*) + _lt_dar_needs_single_mod=yes ;; + esac + ;; + esac if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else @@ -1132,12 +1163,12 @@ m4_defun([_LT_DARWIN_LINKER_FEATURES], output_verbose_link_cmd=func_echo_all _LT_TAGVAR(archive_cmds, $1)="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" _LT_TAGVAR(module_cmds, $1)="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" - _LT_TAGVAR(module_expsym_cmds, $1)="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(module_expsym_cmds, $1)="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" m4_if([$1], [CXX], -[ if test yes != "$lt_cv_apple_cc_single_mod"; then +[ if test yes = "$_lt_dar_needs_single_mod" -a yes != "$lt_cv_apple_cc_single_mod"; then _LT_TAGVAR(archive_cmds, $1)="\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dsymutil" - _LT_TAGVAR(archive_expsym_cmds, $1)="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" + _LT_TAGVAR(archive_expsym_cmds, $1)="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -r -keep_private_externs -nostdlib -o \$lib-master.o \$libobjs~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$lib-master.o \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring$_lt_dar_export_syms$_lt_dsymutil" fi ],[]) else @@ -1251,7 +1282,8 @@ _LT_DECL([], [ECHO], [1], [An echo progr # _LT_WITH_SYSROOT # ---------------- AC_DEFUN([_LT_WITH_SYSROOT], -[AC_MSG_CHECKING([for sysroot]) +[m4_require([_LT_DECL_SED])dnl +AC_MSG_CHECKING([for sysroot]) AC_ARG_WITH([sysroot], [AS_HELP_STRING([--with-sysroot@<:@=DIR@:>@], [Search for dependent libraries within DIR (or the compiler's sysroot @@ -1264,11 +1296,13 @@ lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then - lt_sysroot=`$CC --print-sysroot 2>/dev/null` + # Trim trailing / since we'll always append absolute paths and we want + # to avoid //, if only for less confusing output for the user. + lt_sysroot=`$CC --print-sysroot 2>/dev/null | $SED 's:/\+$::'` fi ;; #( /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( @@ -1298,7 +1332,7 @@ ia64-*-hpux*) # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; @@ -1315,7 +1349,7 @@ ia64-*-hpux*) echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then if test yes = "$lt_cv_prog_gnu_ld"; then - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; @@ -1327,7 +1361,7 @@ ia64-*-hpux*) ;; esac else - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; @@ -1349,7 +1383,7 @@ mips64*-*linux*) echo '[#]line '$LINENO' "configure"' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then emul=elf - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; @@ -1357,7 +1391,7 @@ mips64*-*linux*) emul="${emul}64" ;; esac - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; @@ -1365,7 +1399,7 @@ mips64*-*linux*) emul="${emul}ltsmip" ;; esac - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; @@ -1376,7 +1410,7 @@ mips64*-*linux*) ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) +s390*-*linux*|s390*-*tpf*|sparc*-*linux*|x86_64-gnu*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when @@ -1385,14 +1419,14 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux* # not appear in the list. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; - x86_64-*linux*) - case `/usr/bin/file conftest.o` in + x86_64-*linux*|x86_64-gnu*) + case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; @@ -1420,7 +1454,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux* x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; - x86_64-*linux*) + x86_64-*linux*|x86_64-gnu*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) @@ -1460,7 +1494,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux* # options accordingly. echo 'int i;' > conftest.$ac_ext if AC_TRY_EVAL(ac_compile); then - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) @@ -1499,9 +1533,22 @@ need_locks=$enable_libtool_lock m4_defun([_LT_PROG_AR], [AC_CHECK_TOOLS(AR, [ar], false) : ${AR=ar} -: ${AR_FLAGS=cru} _LT_DECL([], [AR], [1], [The archiver]) -_LT_DECL([], [AR_FLAGS], [1], [Flags to create an archive]) + +# Use ARFLAGS variable as AR's operation code to sync the variable naming with +# Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have +# higher priority because that's what people were doing historically (setting +# ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS +# variable obsoleted/removed. + +test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} +lt_ar_flags=$AR_FLAGS +_LT_DECL([], [lt_ar_flags], [0], [Flags to create an archive (by configure)]) + +# Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override +# by AR_FLAGS because that was never working and AR_FLAGS is about to die. +_LT_DECL([], [AR_FLAGS], [\@S|@{ARFLAGS-"\@S|@lt_ar_flags"}], + [Flags to create an archive]) AC_CACHE_CHECK([for archiver @FILE support], [lt_cv_ar_at_file], [lt_cv_ar_at_file=no @@ -1540,7 +1587,7 @@ AC_CHECK_TOOL(STRIP, strip, :) test -z "$STRIP" && STRIP=: _LT_DECL([], [STRIP], [1], [A symbol stripping program]) -AC_CHECK_TOOL(RANLIB, ranlib, :) +AC_REQUIRE([AC_PROG_RANLIB]) test -z "$RANLIB" && RANLIB=: _LT_DECL([], [RANLIB], [1], [Commands used to install an old-style archive]) @@ -1551,15 +1598,8 @@ old_postinstall_cmds='chmod 644 $oldlib' old_postuninstall_cmds= if test -n "$RANLIB"; then - case $host_os in - bitrig* | openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" - ;; - esac old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in @@ -1691,14 +1731,14 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [d lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. + gnu* | ironclad*) + # Under GNU Hurd and Ironclad, this test is not required because there + # is no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; - cygwin* | mingw* | cegcc*) + cygwin* | mingw* | windows* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, @@ -1720,7 +1760,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [d lt_cv_sys_max_cmd_len=8192; ;; - bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` @@ -1763,7 +1803,7 @@ AC_CACHE_VAL([lt_cv_sys_max_cmd_len], [d sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[[ ]]//'` + lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[[ ]]//'` else lt_cv_sys_max_cmd_len=32768 fi @@ -1880,11 +1920,11 @@ else /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); +int fnord (void) __attribute__((visibility("default"))); #endif -int fnord () { return 42; } -int main () +int fnord (void) { return 42; } +int main (void) { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; @@ -1941,7 +1981,7 @@ else lt_cv_dlopen_self=yes ;; - mingw* | pw32* | cegcc*) + mingw* | windows* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; @@ -2213,26 +2253,35 @@ m4_defun([_LT_CMD_STRIPLIB], striplib= old_striplib= AC_MSG_CHECKING([whether stripping libraries is possible]) -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - AC_MSG_RESULT([yes]) +if test -z "$STRIP"; then + AC_MSG_RESULT([no]) else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP"; then + if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) + else + case $host_os in + darwin*) + # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" AC_MSG_RESULT([yes]) - else + ;; + freebsd*) + if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + AC_MSG_RESULT([yes]) + else + AC_MSG_RESULT([no]) + fi + ;; + *) AC_MSG_RESULT([no]) - fi - ;; - *) - AC_MSG_RESULT([no]) - ;; - esac + ;; + esac + fi fi _LT_DECL([], [old_striplib], [1], [Commands to strip libraries]) _LT_DECL([], [striplib], [1]) @@ -2300,7 +2349,7 @@ if test yes = "$GCC"; then *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in - mingw* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; + mingw* | windows* | cegcc*) lt_sed_strip_eq='s|=\([[A-Za-z]]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` @@ -2358,7 +2407,7 @@ BEGIN {RS = " "; FS = "/|\n";} { # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in - mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + mingw* | windows* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([[A-Za-z]]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` @@ -2433,7 +2482,7 @@ aix[[4-9]]*) # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl - # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # linker flag in LDFLAGS as well, or --enable-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the @@ -2527,7 +2576,7 @@ bsdi[[45]]*) # libtool to hard-code these into programs ;; -cygwin* | mingw* | pw32* | cegcc*) +cygwin* | mingw* | windows* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no @@ -2538,15 +2587,29 @@ cygwin* | mingw* | pw32* | cegcc*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' + # If user builds GCC with multilib enabled, + # it should just install on $(libdir) + # not on $(libdir)/../bin or 32 bits dlls would override 64 bit ones. + if test xyes = x"$multilib"; then + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + $install_prog $dir/$dlname $destdir/$dlname~ + chmod a+x $destdir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib $destdir/$dlname'\'' || exit \$?; + fi' + else + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + fi postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' @@ -2555,30 +2618,30 @@ cygwin* | mingw* | pw32* | cegcc*) case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' m4_if([$1], [],[ sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api"]) ;; - mingw* | cegcc*) + mingw* | windows* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' + library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; - *,cl*) - # Native MSVC + *,cl* | *,icl*) + # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in - mingw*) + mingw* | windows*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' @@ -2591,7 +2654,7 @@ m4_if([$1], [],[ done IFS=$lt_save_ifs # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([[a-zA-Z]]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form @@ -2628,7 +2691,7 @@ m4_if([$1], [],[ ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[[.]]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; @@ -2661,7 +2724,7 @@ dgux*) shlibpath_var=LD_LIBRARY_PATH ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then @@ -2685,7 +2748,21 @@ freebsd* | dragonfly*) need_version=yes ;; esac - shlibpath_var=LD_LIBRARY_PATH + case $host_cpu in + powerpc64) + # On FreeBSD bi-arch platforms, a different variable is used for 32-bit + # binaries. See . + AC_COMPILE_IFELSE( + [AC_LANG_SOURCE( + [[int test_pointer_size[sizeof (void *) - 5]; + ]])], + [shlibpath_var=LD_LIBRARY_PATH], + [shlibpath_var=LD_32_LIBRARY_PATH]) + ;; + *) + shlibpath_var=LD_LIBRARY_PATH + ;; + esac case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes @@ -2715,8 +2792,9 @@ haiku*) soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes + sys_lib_search_path_spec='/boot/system/non-packaged/develop/lib /boot/system/develop/lib' + sys_lib_dlsearch_path_spec='/boot/home/config/non-packaged/lib /boot/home/config/lib /boot/system/non-packaged/lib /boot/system/lib' + hardcode_into_libs=no ;; hpux9* | hpux10* | hpux11*) @@ -2826,7 +2904,7 @@ linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no - library_names_spec='$libname$release$shared_ext' + library_names_spec='$libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH @@ -2838,8 +2916,9 @@ linux*android*) hardcode_into_libs=yes dynamic_linker='Android linker' - # Don't embed -rpath directories since the linker doesn't support them. - _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' + # -rpath works at least for libraries that are not overridden by + # libraries installed in system locations. + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; # This must be glibc/ELF. @@ -2876,7 +2955,7 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" - # Ideally, we could use ldconfig to report *all* directores which are + # Ideally, we could use ldconfig to report *all* directories which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, @@ -2896,6 +2975,18 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu dynamic_linker='GNU/Linux ld.so' ;; +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + netbsd*) version_type=sunos need_lib_prefix=no @@ -2914,6 +3005,18 @@ netbsd*) hardcode_into_libs=yes ;; +*-mlibc) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='mlibc ld.so' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' @@ -2933,7 +3036,7 @@ newsos6) dynamic_linker='ldqnx.so' ;; -openbsd* | bitrig*) +openbsd*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no @@ -2993,6 +3096,17 @@ rdos*) dynamic_linker=no ;; +serenity*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + dynamic_linker='SerenityOS LibELF' + ;; + solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no @@ -3090,6 +3204,21 @@ uts4*) shlibpath_var=LD_LIBRARY_PATH ;; +emscripten*) + version_type=none + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + dynamic_linker="Emscripten linker" + _LT_COMPILER_PIC($1)='-fPIC' + _LT_TAGVAR(archive_cmds, $1)='$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib -s EXPORTED_FUNCTIONS=@$output_objdir/$soname.expsym' + _LT_TAGVAR(archive_cmds_need_lc, $1)=no + _LT_TAGVAR(no_undefined_flag, $1)= + ;; + *) dynamic_linker=no ;; @@ -3265,7 +3394,7 @@ if test yes = "$GCC"; then # Check if gcc -print-prog-name=ld gives a path. AC_MSG_CHECKING([for ld used by $CC]) case $host in - *-*-mingw*) + *-*-mingw* | *-*-windows*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) @@ -3374,7 +3503,7 @@ case $reload_flag in esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi @@ -3446,7 +3575,6 @@ lt_cv_deplibs_check_method='unknown' # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure @@ -3463,7 +3591,7 @@ beos*) bsdi[[45]]*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; @@ -3473,7 +3601,7 @@ cygwin*) lt_cv_file_magic_cmd='func_win32_libid' ;; -mingw* | pw32*) +mingw* | windows* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. @@ -3482,7 +3610,7 @@ mingw* | pw32*) lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. - lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64|pe-aarch64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; @@ -3497,14 +3625,14 @@ darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[[3-9]]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac @@ -3518,7 +3646,7 @@ haiku*) ;; hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[[0-9]][[0-9]][[0-9]]|ELF-[[0-9]][[0-9]]) shared object file - IA64' @@ -3555,7 +3683,11 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu lt_cv_deplibs_check_method=pass_all ;; -netbsd*) +*-mlibc) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|_pic\.a)$' else @@ -3565,7 +3697,7 @@ netbsd*) newos6*) lt_cv_deplibs_check_method='file_magic ELF [[0-9]][[0-9]]*-bit [[ML]]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; @@ -3573,7 +3705,7 @@ newos6*) lt_cv_deplibs_check_method=pass_all ;; -openbsd* | bitrig*) +openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[[^/]]+(\.so\.[[0-9]]+\.[[0-9]]+|\.so|_pic\.a)$' else @@ -3589,6 +3721,10 @@ rdos*) lt_cv_deplibs_check_method=pass_all ;; +serenity*) + lt_cv_deplibs_check_method=pass_all + ;; + solaris*) lt_cv_deplibs_check_method=pass_all ;; @@ -3637,7 +3773,7 @@ file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in - mingw* | pw32*) + mingw* | windows* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else @@ -3689,16 +3825,16 @@ else # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in - mingw*) lt_bad_file=conftest.nm/nofile ;; + mingw* | windows*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac - case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 @@ -3724,7 +3860,7 @@ else # Let the user override the test. else AC_CHECK_TOOLS(DUMPBIN, [dumpbin "link -dump"], :) - case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; @@ -3780,7 +3916,7 @@ lt_cv_sharedlib_from_linklib_cmd, [lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in -cygwin* | mingw* | pw32* | cegcc*) +cygwin* | mingw* | windows* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in @@ -3812,16 +3948,16 @@ _LT_DECL([], [sharedlib_from_linklib_cmd m4_defun([_LT_PATH_MANIFEST_TOOL], [AC_CHECK_TOOL(MANIFEST_TOOL, mt, :) test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt -AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_mainfest_tool], - [lt_cv_path_mainfest_tool=no +AC_CACHE_CHECK([if $MANIFEST_TOOL is a manifest tool], [lt_cv_path_manifest_tool], + [lt_cv_path_manifest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&AS_MESSAGE_LOG_FD $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&AS_MESSAGE_LOG_FD if $GREP 'Manifest Tool' conftest.out > /dev/null; then - lt_cv_path_mainfest_tool=yes + lt_cv_path_manifest_tool=yes fi rm -f conftest*]) -if test yes != "$lt_cv_path_mainfest_tool"; then +if test yes != "$lt_cv_path_manifest_tool"; then MANIFEST_TOOL=: fi _LT_DECL([], [MANIFEST_TOOL], [1], [Manifest tool])dnl @@ -3850,7 +3986,7 @@ AC_DEFUN([LT_LIB_M], [AC_REQUIRE([AC_CANONICAL_HOST])dnl LIBM= case $host in -*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-pw32* | *-*-darwin*) +*-*-beos* | *-*-cegcc* | *-*-cygwin* | *-*-haiku* | *-*-mingw* | *-*-pw32* | *-*-darwin*) # These system don't have libm, or don't need it ;; *-ncr-sysv4.3*) @@ -3925,7 +4061,7 @@ case $host_os in aix*) symcode='[[BCDT]]' ;; -cygwin* | mingw* | pw32* | cegcc*) +cygwin* | mingw* | windows* | pw32* | cegcc*) symcode='[[ABCDGISTW]]' ;; hpux*) @@ -3940,7 +4076,7 @@ osf*) symcode='[[BCDEGQRST]]' ;; solaris*) - symcode='[[BDRT]]' + symcode='[[BCDRT]]' ;; sco3.2v5*) symcode='[[DT]]' @@ -3964,7 +4100,7 @@ esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. - lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" @@ -3982,20 +4118,20 @@ fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ @@ -4004,7 +4140,7 @@ $lt_c_name_lib_hook\ # Handle CRLF in mingw tool chain opt_cr= case $build_os in -mingw*) +mingw* | windows*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac @@ -4019,7 +4155,7 @@ for ac_symprfx in "" "_"; do if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. - # Also find C++ and __fastcall symbols from MSVC++, + # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK ['"\ " {last_section=section; section=\$ 3};"\ @@ -4037,9 +4173,9 @@ for ac_symprfx in "" "_"; do " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx]" else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[[ ]]\($symcode$symcode*\)[[ ]][[ ]]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no @@ -4055,13 +4191,14 @@ void nm_test_func(void){} #ifdef __cplusplus } #endif -int main(){nm_test_var='a';nm_test_func();return(0);} +int main(void){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if AC_TRY_EVAL(ac_compile); then # Now try to grab the symbols. nlist=conftest.nm - if AC_TRY_EVAL(NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) && test -s "$nlist"; then + $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&AS_MESSAGE_LOG_FD + if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&AS_MESSAGE_LOG_FD && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" @@ -4231,7 +4368,7 @@ m4_if([$1], [CXX], [ beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) # PIC is the default for these OSes. ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) + mingw* | windows* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style @@ -4307,7 +4444,7 @@ m4_if([$1], [CXX], [ ;; esac ;; - mingw* | cygwin* | os2* | pw32* | cegcc*) + mingw* | windows* | cygwin* | os2* | pw32* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], @@ -4326,7 +4463,7 @@ m4_if([$1], [CXX], [ ;; esac ;; - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) # FreeBSD uses GNU C++ ;; hpux9* | hpux10* | hpux11*) @@ -4409,7 +4546,7 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' @@ -4433,7 +4570,9 @@ m4_if([$1], [CXX], [ ;; esac ;; - netbsd*) + netbsd* | netbsdelf*-gnu) + ;; + *-mlibc) ;; *qnx* | *nto*) # QNX uses GNU C++, but need to define -shared option too, otherwise @@ -4463,6 +4602,8 @@ m4_if([$1], [CXX], [ ;; psos*) ;; + serenity*) + ;; solaris*) case $cc_basename in CC* | sunCC*) @@ -4555,7 +4696,7 @@ m4_if([$1], [CXX], [ # PIC is the default for these OSes. ;; - mingw* | cygwin* | pw32* | os2* | cegcc*) + mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style @@ -4659,7 +4800,7 @@ m4_if([$1], [CXX], [ esac ;; - mingw* | cygwin* | pw32* | os2* | cegcc*) + mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). m4_if([$1], [GCJ], [], @@ -4701,6 +4842,12 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' ;; + *flang* | ftn | f18* | f95*) + # Flang compiler. + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) @@ -4745,7 +4892,7 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-qstaticlink' ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [[1-7]].* | *Sun*Fortran*\ 8.[[0-3]]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' @@ -4783,6 +4930,12 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' ;; + *-mlibc) + _LT_TAGVAR(lt_prog_compiler_wl, $1)='-Wl,' + _LT_TAGVAR(lt_prog_compiler_pic, $1)='-fPIC' + _LT_TAGVAR(lt_prog_compiler_static, $1)='-static' + ;; + *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. @@ -4799,6 +4952,9 @@ m4_if([$1], [CXX], [ _LT_TAGVAR(lt_prog_compiler_static, $1)='-non_shared' ;; + serenity*) + ;; + solaris*) _LT_TAGVAR(lt_prog_compiler_pic, $1)='-KPIC' _LT_TAGVAR(lt_prog_compiler_static, $1)='-Bstatic' @@ -4928,15 +5084,15 @@ m4_if([$1], [CXX], [ if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else - _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi ;; pw32*) _LT_TAGVAR(export_symbols_cmds, $1)=$ltdll_cmds ;; - cygwin* | mingw* | cegcc*) + cygwin* | mingw* | windows* | cegcc*) case $cc_basename in - cl*) + cl* | icl*) _LT_TAGVAR(exclude_expsyms, $1)='_NULL_IMPORT_DESCRIPTOR|_IMPORT_DESCRIPTOR_.*' ;; *) @@ -4992,21 +5148,18 @@ dnl Note also adjust exclude_expsyms for extract_expsyms_cmds= case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time + cygwin* | mingw* | windows* | pw32* | cegcc*) + # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) + # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; - openbsd* | bitrig*) - with_gnu_ld=no - ;; esac _LT_TAGVAR(ld_shlibs, $1)=yes @@ -5053,7 +5206,7 @@ dnl Note also adjust exclude_expsyms for _LT_TAGVAR(whole_archive_flag_spec, $1)= fi supports_anon_versioning=no - case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in + case `$LD -v | $SED -e 's/([[^)]]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [[01]].* | *\ 2.[[0-9]].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... @@ -5107,7 +5260,7 @@ _LT_EOF fi ;; - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, $1) is actually meaningless, # as there is no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-L$libdir' @@ -5117,6 +5270,7 @@ _LT_EOF _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes _LT_TAGVAR(export_symbols_cmds, $1)='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[[BCDGRS]][[ ]]/s/.*[[ ]]\([[^ ]]*\)/\1 DATA/;s/^.*[[ ]]__nm__\([[^ ]]*\)[[ ]][[^ ]]*/\1 DATA/;/^I[[ ]]/d;/^[[AITW]][[ ]]/s/.* //'\'' | sort | uniq > $export_symbols' _LT_TAGVAR(exclude_expsyms, $1)=['[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname'] + _LT_TAGVAR(file_list_spec, $1)='@' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' @@ -5136,7 +5290,7 @@ _LT_EOF haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=no ;; os2*) @@ -5163,8 +5317,9 @@ _LT_EOF cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' ;; interix[[3-9]]*) @@ -5179,7 +5334,7 @@ _LT_EOF # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) @@ -5222,7 +5377,7 @@ _LT_EOF _LT_TAGVAR(compiler_needs_object, $1)=yes ;; esac - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 _LT_TAGVAR(whole_archive_flag_spec, $1)='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' _LT_TAGVAR(compiler_needs_object, $1)=yes @@ -5234,13 +5389,14 @@ _LT_EOF if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' _LT_TAGVAR(export_dynamic_flag_spec, $1)='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) @@ -5250,7 +5406,7 @@ _LT_EOF _LT_TAGVAR(archive_cmds, $1)='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi @@ -5261,7 +5417,12 @@ _LT_EOF fi ;; - netbsd*) + *-mlibc) + _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= @@ -5382,7 +5543,7 @@ _LT_EOF if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then _LT_TAGVAR(export_symbols_cmds, $1)='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && ([substr](\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else - _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + _LT_TAGVAR(export_symbols_cmds, $1)='`func_echo_all $NM | $SED -e '\''s/B\([[^B]]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && ([substr](\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no @@ -5563,14 +5724,14 @@ _LT_EOF _LT_TAGVAR(export_dynamic_flag_spec, $1)=-rdynamic ;; - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in - cl*) - # Native MSVC + cl* | icl*) + # Native MSVC or ICC _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=yes @@ -5580,14 +5741,14 @@ _LT_EOF # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. - _LT_TAGVAR(archive_cmds, $1)='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + _LT_TAGVAR(archive_cmds, $1)='$CC -Fe$output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' _LT_TAGVAR(archive_expsym_cmds, $1)='if _LT_DLL_DEF_P([$export_symbols]); then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + $CC -Fe$tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, $1)='true' @@ -5611,7 +5772,7 @@ _LT_EOF fi' ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' _LT_TAGVAR(allow_undefined_flag, $1)=unsupported # Tell ltmain to make .lib files, not .a files. @@ -5659,7 +5820,7 @@ _LT_EOF ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='-R$libdir' _LT_TAGVAR(hardcode_direct, $1)=yes @@ -5799,11 +5960,15 @@ _LT_EOF # Fabrice Bellard et al's Tiny C Compiler _LT_TAGVAR(ld_shlibs, $1)=yes _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-rpath $wl$libdir' ;; esac ;; - netbsd*) + *-mlibc) + ;; + + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else @@ -5825,7 +5990,7 @@ _LT_EOF *nto* | *qnx*) ;; - openbsd* | bitrig*) + openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no @@ -5868,8 +6033,9 @@ _LT_EOF cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' ;; osf3*) @@ -5903,6 +6069,9 @@ _LT_EOF _LT_TAGVAR(hardcode_libdir_separator, $1)=: ;; + serenity*) + ;; + solaris*) _LT_TAGVAR(no_undefined_flag, $1)=' -z defs' if test yes = "$GCC"; then @@ -6161,7 +6330,7 @@ _LT_TAGDECL([], [hardcode_direct], [0], _LT_TAGDECL([], [hardcode_direct_absolute], [0], [Set to "yes" if using DIR/libNAME$shared_ext during linking hardcodes DIR into the resulting binary and the resulting library dependency is - "absolute", i.e impossible to change by setting $shlibpath_var if the + "absolute", i.e. impossible to change by setting $shlibpath_var if the library is relocated]) _LT_TAGDECL([], [hardcode_minus_L], [0], [Set to "yes" if using the -LDIR flag during linking hardcodes DIR @@ -6219,7 +6388,7 @@ _LT_TAGVAR(objext, $1)=$objext lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' +lt_simple_link_test_code='int main(void){return(0);}' _LT_TAG_COMPILER # Save the default compiler, since it gets overwritten when the other @@ -6404,8 +6573,7 @@ if test yes != "$_lt_caught_CXX_error"; wlarc='$wl' # ancient GNU ld didn't support --whole-archive et. al. - if eval "`$CC -print-prog-name=ld` --help 2>&1" | - $GREP 'no-whole-archive' > /dev/null; then + if $LD --help 2>&1 | $GREP 'no-whole-archive' > /dev/null; then _LT_TAGVAR(whole_archive_flag_spec, $1)=$wlarc'--whole-archive$convenience '$wlarc'--no-whole-archive' else _LT_TAGVAR(whole_archive_flag_spec, $1)= @@ -6425,7 +6593,7 @@ if test yes != "$_lt_caught_CXX_error"; # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"' else GXX=no @@ -6634,10 +6802,10 @@ if test yes != "$_lt_caught_CXX_error"; esac ;; - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) case $GXX,$cc_basename in - ,cl* | no,cl*) - # Native MSVC + ,cl* | no,cl* | ,icl* | no,icl*) + # Native MSVC or ICC # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. _LT_TAGVAR(hardcode_libdir_flag_spec, $1)=' ' @@ -6687,6 +6855,7 @@ if test yes != "$_lt_caught_CXX_error"; _LT_TAGVAR(allow_undefined_flag, $1)=unsupported _LT_TAGVAR(always_export_symbols, $1)=no _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then _LT_TAGVAR(archive_cmds, $1)='$CC -shared -nostdlib $predep_objects $libobjs $deplibs $postdep_objects $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' @@ -6733,8 +6902,9 @@ if test yes != "$_lt_caught_CXX_error"; cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' - _LT_TAGVAR(old_archive_From_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + _LT_TAGVAR(old_archive_from_new_cmds, $1)='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' _LT_TAGVAR(enable_shared_with_static_runtimes, $1)=yes + _LT_TAGVAR(file_list_spec, $1)='@' ;; dgux*) @@ -6765,7 +6935,7 @@ if test yes != "$_lt_caught_CXX_error"; _LT_TAGVAR(archive_cmds_need_lc, $1)=no ;; - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) # FreeBSD 3 and later use GNU C++ and GNU ld with standard ELF # conventions _LT_TAGVAR(ld_shlibs, $1)=yes @@ -6773,7 +6943,7 @@ if test yes != "$_lt_caught_CXX_error"; haiku*) _LT_TAGVAR(archive_cmds, $1)='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - _LT_TAGVAR(link_all_deplibs, $1)=yes + _LT_TAGVAR(link_all_deplibs, $1)=no ;; hpux9*) @@ -6800,7 +6970,7 @@ if test yes != "$_lt_caught_CXX_error"; # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $EGREP "[[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -6865,7 +7035,7 @@ if test yes != "$_lt_caught_CXX_error"; # explicitly linking system object files so we need to strip them # from the output so that they don't get included in the library # dependencies. - output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP "\-L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' + output_verbose_link_cmd='templist=`($CC -b $CFLAGS -v conftest.$objext 2>&1) | $GREP " [[-]]L"`; list= ; for z in $templist; do case $z in conftest.$objext) list="$list $z";; *.$objext);; *) list="$list $z";;esac; done; func_echo_all "$list"' ;; *) if test yes = "$GXX"; then @@ -6902,7 +7072,7 @@ if test yes != "$_lt_caught_CXX_error"; # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. _LT_TAGVAR(archive_cmds, $1)='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - _LT_TAGVAR(archive_expsym_cmds, $1)='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + _LT_TAGVAR(archive_expsym_cmds, $1)='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; irix5* | irix6*) case $cc_basename in @@ -7042,13 +7212,13 @@ if test yes != "$_lt_caught_CXX_error"; _LT_TAGVAR(archive_cmds, $1)='$CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' if test yes = "$supports_anon_versioning"; then _LT_TAGVAR(archive_expsym_cmds, $1)='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC -qmkshrobj $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C++ 5.9 _LT_TAGVAR(no_undefined_flag, $1)=' -zdefs' @@ -7097,6 +7267,10 @@ if test yes != "$_lt_caught_CXX_error"; esac ;; + *-mlibc) + _LT_TAGVAR(ld_shlibs, $1)=yes + ;; + netbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then _LT_TAGVAR(archive_cmds, $1)='$LD -Bshareable -o $lib $predep_objects $libobjs $deplibs $postdep_objects $linker_flags' @@ -7113,7 +7287,7 @@ if test yes != "$_lt_caught_CXX_error"; _LT_TAGVAR(ld_shlibs, $1)=yes ;; - openbsd* | bitrig*) + openbsd*) if test -f /usr/libexec/ld.so; then _LT_TAGVAR(hardcode_direct, $1)=yes _LT_TAGVAR(hardcode_shlibpath_var, $1)=no @@ -7204,7 +7378,7 @@ if test yes != "$_lt_caught_CXX_error"; # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"' else # FIXME: insert proper C++ library support @@ -7219,6 +7393,9 @@ if test yes != "$_lt_caught_CXX_error"; _LT_TAGVAR(ld_shlibs, $1)=no ;; + serenity*) + ;; + sunos4*) case $cc_basename in CC*) @@ -7288,7 +7465,7 @@ if test yes != "$_lt_caught_CXX_error"; # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -shared $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"' else # g++ 2.7 appears to require '-G' NOT '-shared' on this # platform. @@ -7299,7 +7476,7 @@ if test yes != "$_lt_caught_CXX_error"; # Commands to make compiler produce verbose output that lists # what "hidden" libraries, object files and flags are used when # linking a shared library. - output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP "\-L"' + output_verbose_link_cmd='$CC -G $CFLAGS -v conftest.$objext 2>&1 | $GREP -v "^Configured with:" | $GREP " [[-]]L"' fi _LT_TAGVAR(hardcode_libdir_flag_spec, $1)='$wl-R $wl$libdir' @@ -7537,10 +7714,11 @@ if AC_TRY_EVAL(ac_compile); then case $prev$p in -L* | -R* | -l*) - # Some compilers place space between "-{L,R}" and the path. + # Some compilers place space between "-{L,R,l}" and the path. # Remove the space. - if test x-L = "$p" || - test x-R = "$p"; then + if test x-L = x"$p" || + test x-R = x"$p" || + test x-l = x"$p"; then prev=$p continue fi @@ -8186,6 +8364,14 @@ _LT_DECL([], [DLLTOOL], [1], [DLL creati AC_SUBST([DLLTOOL]) ]) +# _LT_DECL_FILECMD +# ---------------- +# Check for a file(cmd) program that can be used to detect file type and magic +m4_defun([_LT_DECL_FILECMD], +[AC_CHECK_PROG([FILECMD], [file], [file], [:]) +_LT_DECL([], [FILECMD], [1], [A file(cmd) program that detects file types]) +])# _LD_DECL_FILECMD + # _LT_DECL_SED # ------------ # Check for a fully-functional sed program, that truncates @@ -8198,71 +8384,6 @@ _LT_DECL([], [SED], [1], [A sed program _LT_DECL([], [Xsed], ["\$SED -e 1s/^X//"], [Sed that helps us avoid accidentally triggering echo(1) options like -n]) ])# _LT_DECL_SED - -m4_ifndef([AC_PROG_SED], [ -# NOTE: This macro has been submitted for inclusion into # -# GNU Autoconf as AC_PROG_SED. When it is available in # -# a released version of Autoconf we should remove this # -# macro and use it instead. # - -m4_defun([AC_PROG_SED], -[AC_MSG_CHECKING([for a sed that does not truncate output]) -AC_CACHE_VAL(lt_cv_path_SED, -[# Loop through the user's path and test for sed and gsed. -# Then use that list of sed's as ones to test for truncation. -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - test -z "$as_dir" && as_dir=. - for lt_ac_prog in sed gsed; do - for ac_exec_ext in '' $ac_executable_extensions; do - if $as_executable_p "$as_dir/$lt_ac_prog$ac_exec_ext"; then - lt_ac_sed_list="$lt_ac_sed_list $as_dir/$lt_ac_prog$ac_exec_ext" - fi - done - done -done -IFS=$as_save_IFS -lt_ac_max=0 -lt_ac_count=0 -# Add /usr/xpg4/bin/sed as it is typically found on Solaris -# along with /bin/sed that truncates output. -for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do - test ! -f "$lt_ac_sed" && continue - cat /dev/null > conftest.in - lt_ac_count=0 - echo $ECHO_N "0123456789$ECHO_C" >conftest.in - # Check for GNU sed and select it if it is found. - if "$lt_ac_sed" --version 2>&1 < /dev/null | grep 'GNU' > /dev/null; then - lt_cv_path_SED=$lt_ac_sed - break - fi - while true; do - cat conftest.in conftest.in >conftest.tmp - mv conftest.tmp conftest.in - cp conftest.in conftest.nl - echo >>conftest.nl - $lt_ac_sed -e 's/a$//' < conftest.nl >conftest.out || break - cmp -s conftest.out conftest.nl || break - # 10000 chars as input seems more than enough - test 10 -lt "$lt_ac_count" && break - lt_ac_count=`expr $lt_ac_count + 1` - if test "$lt_ac_count" -gt "$lt_ac_max"; then - lt_ac_max=$lt_ac_count - lt_cv_path_SED=$lt_ac_sed - fi - done -done -]) -SED=$lt_cv_path_SED -AC_SUBST([SED]) -AC_MSG_RESULT([$SED]) -])#AC_PROG_SED -])#m4_ifndef - -# Old name: -AU_ALIAS([LT_AC_PROG_SED], [AC_PROG_SED]) dnl aclocal-1.4 backwards compatibility: dnl AC_DEFUN([LT_AC_PROG_SED], []) @@ -8309,7 +8430,7 @@ AC_CACHE_VAL(lt_cv_to_host_file_cmd, [case $host in *-*-mingw* ) case $build in - *-*-mingw* ) # actually msys + *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) @@ -8322,7 +8443,7 @@ AC_CACHE_VAL(lt_cv_to_host_file_cmd, ;; *-*-cygwin* ) case $build in - *-*-mingw* ) # actually msys + *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) @@ -8348,9 +8469,9 @@ AC_CACHE_VAL(lt_cv_to_tool_file_cmd, [#assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in - *-*-mingw* ) + *-*-mingw* | *-*-windows* ) case $build in - *-*-mingw* ) # actually msys + *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac @@ -8365,15 +8486,15 @@ _LT_DECL([to_tool_file_cmd], [lt_cv_to_t # Helper functions for option handling. -*- Autoconf -*- # -# Copyright (C) 2004-2005, 2007-2009, 2011-2015 Free Software -# Foundation, Inc. +# Copyright (C) 2004-2005, 2007-2009, 2011-2019, 2021-2024 Free +# Software Foundation, Inc. # Written by Gary V. Vaughan, 2004 # # This file is free software; the Free Software Foundation gives # unlimited permission to copy and/or distribute it, with or without # modifications, as long as this notice is preserved. -# serial 8 ltoptions.m4 +# serial 10 ltoptions.m4 # This is to help aclocal find these macros, as it can't see m4_define. AC_DEFUN([LTOPTIONS_VERSION], [m4_if([1])]) @@ -8490,7 +8611,7 @@ LT_OPTION_DEFINE([LT_INIT], [win32-dll], [enable_win32_dll=yes case $host in -*-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-cegcc*) +*-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-cegcc*) AC_CHECK_TOOL(AS, as, false) AC_CHECK_TOOL(DLLTOOL, dlltool, false) AC_CHECK_TOOL(OBJDUMP, objdump, false) @@ -8685,29 +8806,39 @@ dnl AC_DEFUN([AM_DISABLE_FAST_INSTALL], # _LT_WITH_AIX_SONAME([DEFAULT]) # ---------------------------------- -# implement the --with-aix-soname flag, and support the `aix-soname=aix' -# and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. DEFAULT -# is either `aix', `both' or `svr4'. If omitted, it defaults to `aix'. +# implement the --enable-aix-soname configure option, and support the +# `aix-soname=aix' and `aix-soname=both' and `aix-soname=svr4' LT_INIT options. +# DEFAULT is either `aix', `both', or `svr4'. If omitted, it defaults to `aix'. m4_define([_LT_WITH_AIX_SONAME], [m4_define([_LT_WITH_AIX_SONAME_DEFAULT], [m4_if($1, svr4, svr4, m4_if($1, both, both, aix))])dnl shared_archive_member_spec= case $host,$enable_shared in power*-*-aix[[5-9]]*,yes) AC_MSG_CHECKING([which variant of shared library versioning to provide]) - AC_ARG_WITH([aix-soname], - [AS_HELP_STRING([--with-aix-soname=aix|svr4|both], + AC_ARG_ENABLE([aix-soname], + [AS_HELP_STRING([--enable-aix-soname=aix|svr4|both], [shared library versioning (aka "SONAME") variant to provide on AIX, @<:@default=]_LT_WITH_AIX_SONAME_DEFAULT[@:>@.])], - [case $withval in - aix|svr4|both) - ;; - *) - AC_MSG_ERROR([Unknown argument to --with-aix-soname]) - ;; - esac - lt_cv_with_aix_soname=$with_aix_soname], - [AC_CACHE_VAL([lt_cv_with_aix_soname], - [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT) - with_aix_soname=$lt_cv_with_aix_soname]) + [case $enableval in + aix|svr4|both) + ;; + *) + AC_MSG_ERROR([Unknown argument to --enable-aix-soname]) + ;; + esac + lt_cv_with_aix_soname=$enable_aix_soname], + [_AC_ENABLE_IF([with], [aix-soname], + [case $withval in + aix|svr4|both) + ;; + *) + AC_MSG_ERROR([Unknown argument to --with-aix-soname]) + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname], + [AC_CACHE_VAL([lt_cv_with_aix_soname], + [lt_cv_with_aix_soname=]_LT_WITH_AIX_SONAME_DEFAULT)]) + enable_aix_soname=$lt_cv_with_aix_soname]) + with_aix_soname=$enable_aix_soname AC_MSG_RESULT([$with_aix_soname]) if test aix != "$with_aix_soname"; then # For the AIX way of multilib, we name the shared archive member @@ -8738,30 +8869,50 @@ LT_OPTION_DEFINE([LT_INIT], [aix-soname= # _LT_WITH_PIC([MODE]) # -------------------- -# implement the --with-pic flag, and support the 'pic-only' and 'no-pic' +# implement the --enable-pic flag, and support the 'pic-only' and 'no-pic' # LT_INIT options. # MODE is either 'yes' or 'no'. If omitted, it defaults to 'both'. m4_define([_LT_WITH_PIC], -[AC_ARG_WITH([pic], - [AS_HELP_STRING([--with-pic@<:@=PKGS@:>@], +[AC_ARG_ENABLE([pic], + [AS_HELP_STRING([--enable-pic@<:@=PKGS@:>@], [try to use only PIC/non-PIC objects @<:@default=use both@:>@])], [lt_p=${PACKAGE-default} - case $withval in - yes|no) pic_mode=$withval ;; - *) - pic_mode=default - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for lt_pkg in $withval; do - IFS=$lt_save_ifs - if test "X$lt_pkg" = "X$lt_p"; then - pic_mode=yes - fi - done - IFS=$lt_save_ifs - ;; - esac], - [pic_mode=m4_default([$1], [default])]) + case $enableval in + yes|no) pic_mode=$enableval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [dnl Continue to support --with-pic and --without-pic, for backward + dnl compatibility. + _AC_ENABLE_IF([with], [pic], + [lt_p=${PACKAGE-default} + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac], + [pic_mode=m4_default([$1], [default])])] + ) _LT_DECL([], [pic_mode], [0], [What type of objects to build])dnl ])# _LT_WITH_PIC @@ -8797,7 +8948,7 @@ LT_OPTION_DEFINE([LTDL_INIT], [convenien # ltsugar.m4 -- libtool m4 base layer. -*-Autoconf-*- # -# Copyright (C) 2004-2005, 2007-2008, 2011-2015 Free Software +# Copyright (C) 2004-2005, 2007-2008, 2011-2019, 2021-2024 Free Software # Foundation, Inc. # Written by Gary V. Vaughan, 2004 # @@ -8922,7 +9073,8 @@ m4_define([lt_dict_filter], # ltversion.m4 -- version numbers -*- Autoconf -*- # -# Copyright (C) 2004, 2011-2015 Free Software Foundation, Inc. +# Copyright (C) 2004, 2011-2019, 2021-2024 Free Software Foundation, +# Inc. # Written by Scott James Remnant, 2004 # # This file is free software; the Free Software Foundation gives @@ -8931,23 +9083,23 @@ m4_define([lt_dict_filter], # @configure_input@ -# serial 4179 ltversion.m4 +# serial 4441 ltversion.m4 # This file is part of GNU Libtool -m4_define([LT_PACKAGE_VERSION], [2.4.6]) -m4_define([LT_PACKAGE_REVISION], [2.4.6]) +m4_define([LT_PACKAGE_VERSION], [2.5.4]) +m4_define([LT_PACKAGE_REVISION], [2.5.4]) AC_DEFUN([LTVERSION_VERSION], -[macro_version='2.4.6' -macro_revision='2.4.6' +[macro_version='2.5.4' +macro_revision='2.5.4' _LT_DECL(, macro_version, 0, [Which release of libtool.m4 was used?]) _LT_DECL(, macro_revision, 0) ]) # lt~obsolete.m4 -- aclocal satisfying obsolete definitions. -*-Autoconf-*- # -# Copyright (C) 2004-2005, 2007, 2009, 2011-2015 Free Software -# Foundation, Inc. +# Copyright (C) 2004-2005, 2007, 2009, 2011-2019, 2021-2024 Free +# Software Foundation, Inc. # Written by Scott James Remnant, 2004. # # This file is free software; the Free Software Foundation gives @@ -9044,8 +9196,8 @@ m4_ifndef([_LT_PROG_F77], [AC_DEFUN([_L m4_ifndef([_LT_PROG_FC], [AC_DEFUN([_LT_PROG_FC])]) m4_ifndef([_LT_PROG_CXX], [AC_DEFUN([_LT_PROG_CXX])]) -# pkg.m4 - Macros to locate and utilise pkg-config. -*- Autoconf -*- -# serial 11 (pkg-config-0.29.1) +# pkg.m4 - Macros to locate and use pkg-config. -*- Autoconf -*- +# serial 12 (pkg-config-0.29.2) dnl Copyright © 2004 Scott James Remnant . dnl Copyright © 2012-2015 Dan Nicholson @@ -9087,13 +9239,13 @@ dnl dnl See the "Since" comment for each macro you use to see what version dnl of the macros you require. m4_defun([PKG_PREREQ], -[m4_define([PKG_MACROS_VERSION], [0.29.1]) +[m4_define([PKG_MACROS_VERSION], [0.29.2]) m4_if(m4_version_compare(PKG_MACROS_VERSION, [$1]), -1, [m4_fatal([pkg.m4 version $1 or higher is required but ]PKG_MACROS_VERSION[ found])]) ])dnl PKG_PREREQ -dnl PKG_PROG_PKG_CONFIG([MIN-VERSION]) -dnl ---------------------------------- +dnl PKG_PROG_PKG_CONFIG([MIN-VERSION], [ACTION-IF-NOT-FOUND]) +dnl --------------------------------------------------------- dnl Since: 0.16 dnl dnl Search for the pkg-config tool and set the PKG_CONFIG variable to @@ -9101,6 +9253,12 @@ dnl first found in the path. Checks that dnl is at least MIN-VERSION. If MIN-VERSION is not specified, 0.9.0 is dnl used since that's the first version where most current features of dnl pkg-config existed. +dnl +dnl If pkg-config is not found or older than specified, it will result +dnl in an empty PKG_CONFIG variable. To avoid widespread issues with +dnl scripts not checking it, ACTION-IF-NOT-FOUND defaults to aborting. +dnl You can specify [PKG_CONFIG=false] as an action instead, which would +dnl result in pkg-config tests failing, but no bogus error messages. AC_DEFUN([PKG_PROG_PKG_CONFIG], [m4_pattern_forbid([^_?PKG_[A-Z_]+$]) m4_pattern_allow([^PKG_CONFIG(_(PATH|LIBDIR|SYSROOT_DIR|ALLOW_SYSTEM_(CFLAGS|LIBS)))?$]) @@ -9121,6 +9279,9 @@ if test -n "$PKG_CONFIG"; then AC_MSG_RESULT([no]) PKG_CONFIG="" fi +fi +if test -z "$PKG_CONFIG"; then + m4_default([$2], [AC_MSG_ERROR([pkg-config not found])]) fi[]dnl ])dnl PKG_PROG_PKG_CONFIG @@ -9132,7 +9293,7 @@ dnl Check to see whether a particular se dnl PKG_CHECK_MODULES(), but does not set variables or print errors. dnl dnl Please remember that m4 expands AC_REQUIRE([PKG_PROG_PKG_CONFIG]) -dnl only at the first occurence in configure.ac, so if the first place +dnl only at the first occurrence in configure.ac, so if the first place dnl it's called might be skipped (such as if it is within an "if", you dnl have to call PKG_CHECK_EXISTS manually AC_DEFUN([PKG_CHECK_EXISTS], @@ -9188,7 +9349,7 @@ AC_ARG_VAR([$1][_CFLAGS], [C compiler fl AC_ARG_VAR([$1][_LIBS], [linker flags for $1, overriding pkg-config])dnl pkg_failed=no -AC_MSG_CHECKING([for $1]) +AC_MSG_CHECKING([for $2]) _PKG_CONFIG([$1][_CFLAGS], [cflags], [$2]) _PKG_CONFIG([$1][_LIBS], [libs], [$2]) @@ -9198,17 +9359,17 @@ and $1[]_LIBS to avoid the need to call See the pkg-config man page for more details.]) if test $pkg_failed = yes; then - AC_MSG_RESULT([no]) + AC_MSG_RESULT([no]) _PKG_SHORT_ERRORS_SUPPORTED if test $_pkg_short_errors_supported = yes; then - $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` - else - $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` + $1[]_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "$2" 2>&1` + else + $1[]_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "$2" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD + # Put the nasty error message in config.log where it belongs + echo "$$1[]_PKG_ERRORS" >&AS_MESSAGE_LOG_FD - m4_default([$4], [AC_MSG_ERROR( + m4_default([$4], [AC_MSG_ERROR( [Package requirements ($2) were not met: $$1_PKG_ERRORS @@ -9219,8 +9380,8 @@ installed software in a non-standard pre _PKG_TEXT])[]dnl ]) elif test $pkg_failed = untried; then - AC_MSG_RESULT([no]) - m4_default([$4], [AC_MSG_FAILURE( + AC_MSG_RESULT([no]) + m4_default([$4], [AC_MSG_FAILURE( [The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full path to pkg-config. @@ -9230,10 +9391,10 @@ _PKG_TEXT To get pkg-config, see .])[]dnl ]) else - $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS - $1[]_LIBS=$pkg_cv_[]$1[]_LIBS + $1[]_CFLAGS=$pkg_cv_[]$1[]_CFLAGS + $1[]_LIBS=$pkg_cv_[]$1[]_LIBS AC_MSG_RESULT([yes]) - $3 + $3 fi[]dnl ])dnl PKG_CHECK_MODULES @@ -9390,7 +9551,7 @@ AS_IF([test "$AS_TR_SH([with_]m4_tolower # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2020 Free Software Foundation, Inc. +# Copyright (C) 1997-2025 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -9421,7 +9582,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 2006-2020 Free Software Foundation, Inc. +# Copyright (C) 2006-2025 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, Index: usr.sbin/unbound/acx_nlnetlabs.m4 =================================================================== RCS file: /cvs/src/usr.sbin/unbound/acx_nlnetlabs.m4,v diff -u -p -r1.13 acx_nlnetlabs.m4 --- usr.sbin/unbound/acx_nlnetlabs.m4 13 Apr 2024 12:24:57 -0000 1.13 +++ usr.sbin/unbound/acx_nlnetlabs.m4 21 Sep 2026 16:28:30 -0000 @@ -2,7 +2,12 @@ # Copyright 2009, Wouter Wijngaards, NLnet Labs. # BSD licensed. # -# Version 48 +# Version 51 +# 2025-11-06 Fix ACX_CHECK_NONSTRING_ATTRIBUTE to reject clang, that prints +# a warning for 'unknown attribute' when nonstring is used. +# 2025-09-29 add ac_cv_func_malloc_0_nonnull as a cache value for the malloc(0) +# check by ACX_FUNC_MALLOC. +# 2025-09-29 add ACX_CHECK_NONSTRING_ATTRIBUTE, AHX_CONFIG_NONSTRING_ATTRIBUTE. # 2024-01-16 fix to add -l:libssp.a to -lcrypto link check. # and check for getaddrinfo with only header. # 2024-01-15 fix to add crypt32 to -lcrypto link check when checking for gdi32. @@ -71,6 +76,7 @@ # ACX_DEPFLAG - find cc dependency flags. # ACX_DETERMINE_EXT_FLAGS_UNBOUND - find out which flags enable BSD and POSIX. # ACX_CHECK_FORMAT_ATTRIBUTE - find cc printf format syntax. +# ACX_CHECK_NONSTRING_ATTRIBUTE - find cc nonstring attribute syntax. # ACX_CHECK_UNUSED_ATTRIBUTE - find cc variable unused syntax. # ACX_CHECK_FLTO - see if cc supports -flto and use it if so. # ACX_LIBTOOL_C_ONLY - create libtool for C only, improved. @@ -92,6 +98,7 @@ # ACX_FUNC_IOCTLSOCKET - find ioctlsocket, portably. # ACX_FUNC_MALLOC - check malloc, define replacement . # AHX_CONFIG_FORMAT_ATTRIBUTE - config.h text for format. +# AHX_CONFIG_NONSTRING_ATTRIBUTE - config.h text for nonstring. # AHX_CONFIG_UNUSED_ATTRIBUTE - config.h text for unused. # AHX_CONFIG_FSEEKO - define fseeko, ftello fallback. # AHX_CONFIG_RAND_MAX - define RAND_MAX if needed. @@ -490,7 +497,7 @@ AC_DEFUN([AHX_CONFIG_FORMAT_ATTRIBUTE], ]) dnl Check how to mark function arguments as unused. -dnl result in HAVE_ATTR_UNUSED. +dnl result in HAVE_ATTR_UNUSED. dnl Make sure you include AHX_CONFIG_UNUSED_ATTRIBUTE also. AC_DEFUN([ACX_CHECK_UNUSED_ATTRIBUTE], [AC_REQUIRE([AC_PROG_CC]) @@ -525,6 +532,49 @@ if test $ac_cv_c_unused_attribute = yes; fi ])dnl +dnl Check how to mark function arguments as nonstring. +dnl result in HAVE_ATTR_NONSTRING. +dnl Make sure you include AHX_CONFIG_NONSTRING_ATTRIBUTE also. +AC_DEFUN([ACX_CHECK_NONSTRING_ATTRIBUTE], +[AC_REQUIRE([AC_PROG_CC]) +AC_REQUIRE([ACX_CHECK_ERROR_FLAGS]) +BAKCFLAGS="$CFLAGS" +CFLAGS="$CFLAGS $ERRFLAG" +AC_MSG_CHECKING(whether the C compiler (${CC-cc}) accepts the "nonstring" attribute) +AC_CACHE_VAL(ac_cv_c_nonstring_attribute, +[ac_cv_c_nonstring_attribute=no +AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[#include +struct test { + char __attribute__((nonstring)) s[1]; +}; +]], [[ + struct test t = { "1" }; + (void) t; +]])],[ac_cv_c_nonstring_attribute="yes"],[ac_cv_c_nonstring_attribute="no"]) +CFLAGS="$BAKCFLAGS" +]) + +dnl Setup ATTR_NONSTRING config.h parts. +dnl make sure you call ACX_CHECK_NONSTRING_ATTRIBUTE also. +AC_DEFUN([AHX_CONFIG_NONSTRING_ATTRIBUTE], +[ +#if defined(DOXYGEN) +# define ATTR_NONSTRING(x) x +#elif defined(__cplusplus) +# define ATTR_NONSTRING(x) __attribute__((nonstring)) x +#elif defined(HAVE_ATTR_NONSTRING) +# define ATTR_NONSTRING(x) __attribute__((nonstring)) x +#else /* !HAVE_ATTR_NONSTRING */ +# define ATTR_NONSTRING(x) x +#endif /* !HAVE_ATTR_NONSTRING */ +]) + +AC_MSG_RESULT($ac_cv_c_nonstring_attribute) +if test $ac_cv_c_nonstring_attribute = yes; then + AC_DEFINE(HAVE_ATTR_NONSTRING, 1, [Whether the C compiler accepts the "nonstring" attribute]) +fi +])dnl + dnl Pre-fun for ACX_LIBTOOL_C_ONLY AC_DEFUN([ACX_LIBTOOL_C_PRE], [ # skip these tests, we do not need them. @@ -1190,8 +1240,9 @@ dnl detect malloc and provide malloc com dnl $1: unique name for compat code AC_DEFUN([ACX_FUNC_MALLOC], [ - AC_MSG_CHECKING([for GNU libc compatible malloc]) - AC_RUN_IFELSE([AC_LANG_PROGRAM( + AC_CACHE_CHECK([for GNU libc compatible malloc],[ac_cv_func_malloc_0_nonnull], + [ + AC_RUN_IFELSE([AC_LANG_PROGRAM( [[#if defined STDC_HEADERS || defined HAVE_STDLIB_H #include #else @@ -1199,14 +1250,16 @@ char *malloc (); #endif ]], [ if(malloc(0) != 0) return 1;]) ], - [AC_MSG_RESULT([no]) - AC_LIBOBJ(malloc) - AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])] , - [AC_MSG_RESULT([yes]) - AC_DEFINE([HAVE_MALLOC], 1, [If have GNU libc compatible malloc])], - [AC_MSG_RESULT([no (crosscompile)]) - AC_LIBOBJ(malloc) - AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.])] ) + [ac_cv_func_malloc_0_nonnull=no], + [ac_cv_func_malloc_0_nonnull=yes], + [ac_cv_func_malloc_0_nonnull="no (crosscompile)"]) + ]) + AS_IF([test "$ac_cv_func_malloc_0_nonnull" = yes], + [AC_DEFINE([HAVE_MALLOC], 1, [If have GNU libc compatible malloc])], + [ + AC_LIBOBJ(malloc) + AC_DEFINE_UNQUOTED([malloc], [rpl_malloc_$1], [Define if replacement function should be used.]) + ]) ]) dnl Define fallback for fseeko and ftello if needed. Index: usr.sbin/unbound/ax_pthread.m4 =================================================================== RCS file: /cvs/src/usr.sbin/unbound/ax_pthread.m4,v diff -u -p -r1.3 ax_pthread.m4 --- usr.sbin/unbound/ax_pthread.m4 13 Jun 2024 14:30:28 -0000 1.3 +++ usr.sbin/unbound/ax_pthread.m4 21 Sep 2026 16:28:30 -0000 @@ -87,7 +87,7 @@ # modified version of the Autoconf Macro, you may extend this special # exception to the GPL to apply to your modified version as well. -#serial 31 +#serial 32 AU_ALIAS([ACX_PTHREAD], [AX_PTHREAD]) AC_DEFUN([AX_PTHREAD], [ @@ -249,7 +249,22 @@ AS_IF([test "x$ax_pthread_clang" = "xyes # correctly enabled case $host_os in - darwin* | hpux* | linux* | osf* | solaris*) + solaris*) + # Solaris 11.4 introduced XPG7 support and did away with the need for + # _REENTRANT. + + AC_EGREP_CPP([AX_PTHREAD_SOLARIS__REENTRANT], + [ +# undef _XOPEN_SOURCE +# include +# if _XOPEN_VERSION < 700 + AX_PTHREAD_SOLARIS__REENTRANT +# endif + ], + [ax_pthread_check_macro="_REENTRANT"], + [ax_pthread_check_macro="--"]) + ;; + darwin* | hpux* | linux* | osf*) ax_pthread_check_macro="_REENTRANT" ;; Index: usr.sbin/unbound/config.guess =================================================================== RCS file: /cvs/src/usr.sbin/unbound/config.guess,v diff -u -p -r1.18 config.guess --- usr.sbin/unbound/config.guess 31 Aug 2025 21:41:09 -0000 1.18 +++ usr.sbin/unbound/config.guess 21 Sep 2026 16:28:30 -0000 @@ -1,10 +1,10 @@ #! /bin/sh # Attempt to guess a canonical system name. -# Copyright 1992-2025 Free Software Foundation, Inc. +# Copyright 1992-2026 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268 # see below for rationale -timestamp='2025-07-10' +timestamp='2026-05-17' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -60,7 +60,7 @@ version="\ GNU config.guess ($timestamp) Originally written by Per Bothner. -Copyright 1992-2025 Free Software Foundation, Inc. +Copyright 1992-2026 Free Software Foundation, Inc. This is free software; see the source for copying conditions. There is NO warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE." @@ -150,7 +150,7 @@ UNAME_SYSTEM=`(uname -s) 2>/dev/null` || UNAME_VERSION=`(uname -v) 2>/dev/null` || UNAME_VERSION=unknown case $UNAME_SYSTEM in -Linux|GNU|GNU/*) +Ironclad|Linux|GNU|GNU/*) LIBC=unknown set_cc_for_build @@ -167,6 +167,8 @@ Linux|GNU|GNU/*) LIBC=gnu #elif defined(__LLVM_LIBC__) LIBC=llvm + #elif defined(__mlibc__) + LIBC=mlibc #else #include /* First heuristic to detect musl libc. */ @@ -1186,6 +1188,9 @@ EOF sparc:Linux:*:* | sparc64:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; + sw_64:Linux:*:*) + GUESS=$UNAME_MACHINE-unknown-linux-$LIBC + ;; tile*:Linux:*:*) GUESS=$UNAME_MACHINE-unknown-linux-$LIBC ;; @@ -1598,10 +1603,10 @@ EOF GUESS=$UNAME_MACHINE-unknown-unleashed$UNAME_RELEASE ;; x86_64:[Ii]ronclad:*:*|i?86:[Ii]ronclad:*:*) - GUESS=$UNAME_MACHINE-pc-ironclad-mlibc + GUESS=$UNAME_MACHINE-pc-ironclad-$LIBC ;; *:[Ii]ronclad:*:*) - GUESS=$UNAME_MACHINE-unknown-ironclad-mlibc + GUESS=$UNAME_MACHINE-unknown-ironclad-$LIBC ;; esac Index: usr.sbin/unbound/config.h.in =================================================================== RCS file: /cvs/src/usr.sbin/unbound/config.h.in,v diff -u -p -r1.35 config.h.in --- usr.sbin/unbound/config.h.in 26 Sep 2025 07:32:36 -0000 1.35 +++ usr.sbin/unbound/config.h.in 21 Sep 2026 16:28:30 -0000 @@ -31,6 +31,9 @@ /* Whether daemon is deprecated */ #undef DEPRECATED_DAEMON +/* Whether X509_NAME_get_text_by_NID is deprecated */ +#undef DEPRECATED_X509_NAME_GET_TEXT_BY_NID + /* Deprecate RSA 1024 bit length, makes that an unsupported key */ #undef DEPRECATE_RSA_1024 @@ -60,12 +63,18 @@ /* Define to 1 if you have the header file. */ #undef HAVE_ARPA_INET_H +/* Define to 1 if you have the `ASN1_STRING_get0_data' function. */ +#undef HAVE_ASN1_STRING_GET0_DATA + /* Whether the C compiler accepts the "fallthrough" attribute */ #undef HAVE_ATTR_FALLTHROUGH /* Whether the C compiler accepts the "format" attribute */ #undef HAVE_ATTR_FORMAT +/* Whether the C compiler accepts the "nonstring" attribute */ +#undef HAVE_ATTR_NONSTRING + /* Whether the C compiler accepts the "noreturn" attribute */ #undef HAVE_ATTR_NORETURN @@ -137,6 +146,10 @@ to 0 if you don't. */ #undef HAVE_DECL_NGTCP2_CRYPTO_ENCRYPT_CB +/* Define to 1 if you have the declaration of `ngtcp2_crypto_ossl_ctx_new', + and to 0 if you don't. */ +#undef HAVE_DECL_NGTCP2_CRYPTO_OSSL_CTX_NEW + /* Define to 1 if you have the declaration of `NID_ED25519', and to 0 if you don't. */ #undef HAVE_DECL_NID_ED25519 @@ -286,6 +299,12 @@ /* Define to 1 if you have the `FIPS_mode' function. */ #undef HAVE_FIPS_MODE +/* Define to 1 if you have the `fnmatch' function. */ +#undef HAVE_FNMATCH + +/* Define to 1 if you have the header file. */ +#undef HAVE_FNMATCH_H + /* Define to 1 if you have the `fork' function. */ #undef HAVE_FORK @@ -510,6 +529,9 @@ /* Define to 1 if you have the header file. */ #undef HAVE_OPENSSL_BN_H +/* Define to 1 if you have the `OPENSSL_cleanup' function. */ +#undef HAVE_OPENSSL_CLEANUP + /* Define to 1 if you have the `OPENSSL_config' function. */ #undef HAVE_OPENSSL_CONFIG @@ -561,12 +583,27 @@ /* Define if you have POSIX threads libraries and header files. */ #undef HAVE_PTHREAD +/* Define to 1 if you have the header file. */ +#undef HAVE_PTHREAD_NP_H + /* Have PTHREAD_PRIO_INHERIT. */ #undef HAVE_PTHREAD_PRIO_INHERIT /* Define to 1 if the system has the type `pthread_rwlock_t'. */ #undef HAVE_PTHREAD_RWLOCK_T +/* Define if pthread_setname_np has the common 2 arguments. */ +#undef HAVE_PTHREAD_SETNAME_NP + +/* Define if pthread_setname_np has only 1 argument. */ +#undef HAVE_PTHREAD_SETNAME_NP1 + +/* Define if pthread_setname_np has 3 arguments. */ +#undef HAVE_PTHREAD_SETNAME_NP3 + +/* Define if pthread_setname_np exists as pthread_set_name_np instead. */ +#undef HAVE_PTHREAD_SET_NAME_NP + /* Define to 1 if the system has the type `pthread_spinlock_t'. */ #undef HAVE_PTHREAD_SPINLOCK_T @@ -667,9 +704,16 @@ /* Define to 1 if you have the `SSL_is_quic' function. */ #undef HAVE_SSL_IS_QUIC +/* Define to 1 if you have the `SSL_set1_dnsname' function. */ +#undef HAVE_SSL_SET1_DNSNAME + /* Define to 1 if you have the `SSL_set1_host' function. */ #undef HAVE_SSL_SET1_HOST +/* Define to 1 if you have the `SSL_set_quic_tls_early_data_enabled' function. + */ +#undef HAVE_SSL_SET_QUIC_TLS_EARLY_DATA_ENABLED + /* Define to 1 if you have the header file. */ #undef HAVE_STDARG_H @@ -732,6 +776,12 @@ /* Define to 1 if `sun_len' is a member of `struct sockaddr_un'. */ #undef HAVE_STRUCT_SOCKADDR_UN_SUN_LEN +/* Define to 1 if `st_mtimensec' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_MTIMENSEC + +/* Define to 1 if `st_mtim.tv_nsec' is a member of `struct stat'. */ +#undef HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC + /* Define if you have Swig libraries and header files. */ #undef HAVE_SWIG @@ -828,6 +878,12 @@ /* Define to 1 if you have the header file. */ #undef HAVE_WS2TCPIP_H +/* Define to 1 if you have the `X509_get_key_usage' function. */ +#undef HAVE_X509_GET_KEY_USAGE + +/* Define to 1 if you have the `X509_NAME_get_text_by_NID' function. */ +#undef HAVE_X509_NAME_GET_TEXT_BY_NID + /* Define to 1 if you have the `X509_VERIFY_PARAM_set1_host' function. */ #undef HAVE_X509_VERIFY_PARAM_SET1_HOST @@ -1379,6 +1435,17 @@ #else /* !HAVE_ATTR_UNUSED */ # define ATTR_UNUSED(x) x #endif /* !HAVE_ATTR_UNUSED */ + + +#if defined(DOXYGEN) +# define ATTR_NONSTRING(x) x +#elif defined(__cplusplus) +# define ATTR_NONSTRING(x) __attribute__((nonstring)) x +#elif defined(HAVE_ATTR_NONSTRING) +# define ATTR_NONSTRING(x) __attribute__((nonstring)) x +#else /* !HAVE_ATTR_NONSTRING */ +# define ATTR_NONSTRING(x) x +#endif /* !HAVE_ATTR_NONSTRING */ #ifndef HAVE_FSEEKO Index: usr.sbin/unbound/config.sub =================================================================== RCS file: /cvs/src/usr.sbin/unbound/config.sub,v diff -u -p -r1.17 config.sub --- usr.sbin/unbound/config.sub 31 Aug 2025 21:41:09 -0000 1.17 +++ usr.sbin/unbound/config.sub 21 Sep 2026 16:28:30 -0000 @@ -1,10 +1,10 @@ #! /bin/sh # Configuration validation subroutine script. -# Copyright 1992-2025 Free Software Foundation, Inc. +# Copyright 1992-2026 Free Software Foundation, Inc. # shellcheck disable=SC2006,SC2268,SC2162 # see below for rationale -timestamp='2025-07-10' +timestamp='2026-05-17' # This file is free software; you can redistribute it and/or modify it # under the terms of the GNU General Public License as published by @@ -76,7 +76,7 @@ Report bugs and patches to . # @@ -622,8 +622,8 @@ MAKEFLAGS= # Identity of this package. PACKAGE_NAME='unbound' PACKAGE_TARNAME='unbound' -PACKAGE_VERSION='1.24.0' -PACKAGE_STRING='unbound 1.24.0' +PACKAGE_VERSION='1.26.1' +PACKAGE_STRING='unbound 1.26.1' PACKAGE_BUGREPORT='unbound-bugs@nlnetlabs.nl or https://github.com/NLnetLabs/unbound/issues' PACKAGE_URL='' @@ -774,6 +774,7 @@ RANLIB ac_ct_AR DLLTOOL OBJDUMP +FILECMD LN_S NM ac_ct_DUMPBIN @@ -885,8 +886,10 @@ enable_pie enable_relro_now enable_shared enable_static +enable_pic with_pic enable_fast_install +enable_aix_soname with_aix_soname with_gnu_ld with_sysroot @@ -1513,7 +1516,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.24.0 to adapt to many kinds of systems. +\`configure' configures unbound 1.26.1 to adapt to many kinds of systems. Usage: $0 [OPTION]... [VAR=VALUE]... @@ -1579,7 +1582,7 @@ fi if test -n "$ac_init_help"; then case $ac_init_help in - short | recursive ) echo "Configuration of unbound 1.24.0:";; + short | recursive ) echo "Configuration of unbound 1.26.1:";; esac cat <<\_ACEOF @@ -1596,8 +1599,13 @@ Optional Features: NOW, to protect GOT and .dtor areas) --enable-shared[=PKGS] build shared libraries [default=yes] --enable-static[=PKGS] build static libraries [default=yes] + --enable-pic[=PKGS] try to use only PIC/non-PIC objects [default=use + both] --enable-fast-install[=PKGS] optimize for fast installation [default=yes] + --enable-aix-soname=aix|svr4|both + shared library versioning (aka "SONAME") variant to + provide on AIX, [default=aix]. --disable-libtool-lock avoid locking (might break parallel builds) --disable-rpath disable hardcoded rpath (default=enabled) --disable-largefile omit support for large files @@ -1677,11 +1685,6 @@ Optional Packages: not exist if you are content with the builtin. --with-username=user set default user that unbound changes to (default user is unbound) - --with-pic[=PKGS] try to use only PIC/non-PIC objects [default=use - both] - --with-aix-soname=aix|svr4|both - shared library versioning (aka "SONAME") variant to - provide on AIX, [default=aix]. --with-gnu-ld assume the C compiler uses GNU ld [default=no] --with-sysroot[=DIR] Search for dependent libraries within DIR (or the compiler's sysroot if not specified). @@ -1832,7 +1835,7 @@ fi test -n "$ac_init_help" && exit $ac_status if $ac_init_version; then cat <<\_ACEOF -unbound configure 1.24.0 +unbound configure 1.26.1 generated by GNU Autoconf 2.71 Copyright (C) 2021 Free Software Foundation, Inc. @@ -2489,7 +2492,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.24.0, which was +It was created by unbound $as_me 1.26.1, which was generated by GNU Autoconf 2.71. Invocation command line was $ $0$ac_configure_args_raw @@ -3251,13 +3254,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu UNBOUND_VERSION_MAJOR=1 -UNBOUND_VERSION_MINOR=24 +UNBOUND_VERSION_MINOR=26 -UNBOUND_VERSION_MICRO=0 +UNBOUND_VERSION_MICRO=1 LIBUNBOUND_CURRENT=9 -LIBUNBOUND_REVISION=33 +LIBUNBOUND_REVISION=40 LIBUNBOUND_AGE=1 # 1.0.0 had 0:12:0 # 1.0.1 had 0:13:0 @@ -3358,6 +3361,13 @@ LIBUNBOUND_AGE=1 # 1.23.0 had 9:31:1 # 1.23.1 had 9:32:1 # 1.24.0 had 9:33:1 +# 1.24.1 had 9:34:1 +# 1.24.2 had 9:35:1 +# 1.25.0 had 9:36:1 +# 1.25.1 had 9:37:1 +# 1.25.2 had 9:38:1 +# 1.26.0 had 9:39:1 +# 1.26.1 had 9:40:1 # Current -- the number of the binary API that we're implementing # Revision -- which iteration of the implementation of the binary @@ -6948,6 +6958,57 @@ fi +BAKCFLAGS="$CFLAGS" +CFLAGS="$CFLAGS $ERRFLAG" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler (${CC-cc}) accepts the \"nonstring\" attribute" >&5 +printf %s "checking whether the C compiler (${CC-cc}) accepts the \"nonstring\" attribute... " >&6; } +if test ${ac_cv_c_nonstring_attribute+y} +then : + printf %s "(cached) " >&6 +else $as_nop + ac_cv_c_nonstring_attribute=no +cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +#include +struct test { + char __attribute__((nonstring)) s[1]; +}; + +int +main (void) +{ + + struct test t = { "1" }; + (void) t; + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + ac_cv_c_nonstring_attribute="yes" +else $as_nop + ac_cv_c_nonstring_attribute="no" +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext +CFLAGS="$BAKCFLAGS" + +fi + + + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_c_nonstring_attribute" >&5 +printf "%s\n" "$ac_cv_c_nonstring_attribute" >&6; } +if test $ac_cv_c_nonstring_attribute = yes; then + +printf "%s\n" "#define HAVE_ATTR_NONSTRING 1" >>confdefs.h + +fi + + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether the C compiler (${CC-cc}) accepts the \"weak\" attribute" >&5 printf %s "checking whether the C compiler (${CC-cc}) accepts the \"weak\" attribute... " >&6; } @@ -7010,7 +7071,14 @@ else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ #include -__attribute__((noreturn)) void f(int x) { printf("%d", x); } +#ifdef STDC_HEADERS +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +__attribute__((noreturn)) void f(int x) { printf("%d", x); exit(1); } int main (void) @@ -7795,8 +7863,8 @@ esac -macro_version='2.4.6' -macro_revision='2.4.6' +macro_version='2.5.4' +macro_revision='2.5.4' @@ -8150,7 +8218,7 @@ if test yes = "$GCC"; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for ld used by $CC" >&5 printf %s "checking for ld used by $CC... " >&6; } case $host in - *-*-mingw*) + *-*-mingw* | *-*-windows*) # gcc leaves a trailing carriage return, which upsets mingw ac_prog=`($CC -print-prog-name=ld) 2>&5 | tr -d '\015'` ;; *) @@ -8277,16 +8345,16 @@ else # Tru64's nm complains that /dev/null is an invalid object file # MSYS converts /dev/null to NUL, MinGW nm treats NUL as empty case $build_os in - mingw*) lt_bad_file=conftest.nm/nofile ;; + mingw* | windows*) lt_bad_file=conftest.nm/nofile ;; *) lt_bad_file=/dev/null ;; esac - case `"$tmp_nm" -B $lt_bad_file 2>&1 | sed '1q'` in + case `"$tmp_nm" -B $lt_bad_file 2>&1 | $SED '1q'` in *$lt_bad_file* | *'Invalid file or object type'*) lt_cv_path_NM="$tmp_nm -B" break 2 ;; *) - case `"$tmp_nm" -p /dev/null 2>&1 | sed '1q'` in + case `"$tmp_nm" -p /dev/null 2>&1 | $SED '1q'` in */dev/null*) lt_cv_path_NM="$tmp_nm -p" break 2 @@ -8424,7 +8492,7 @@ esac fi fi - case `$DUMPBIN -symbols -headers /dev/null 2>&1 | sed '1q'` in + case `$DUMPBIN -symbols -headers /dev/null 2>&1 | $SED '1q'` in *COFF*) DUMPBIN="$DUMPBIN -symbols -headers" ;; @@ -8499,14 +8567,14 @@ else $as_nop lt_cv_sys_max_cmd_len=12288; # 12K is about right ;; - gnu*) - # Under GNU Hurd, this test is not required because there is - # no limit to the length of command line arguments. + gnu* | ironclad*) + # Under GNU Hurd and Ironclad, this test is not required because there + # is no limit to the length of command line arguments. # Libtool will interpret -1 as no limit whatsoever lt_cv_sys_max_cmd_len=-1; ;; - cygwin* | mingw* | cegcc*) + cygwin* | mingw* | windows* | cegcc*) # On Win9x/ME, this test blows up -- it succeeds, but takes # about 5 minutes as the teststring grows exponentially. # Worse, since 9x/ME are not pre-emptively multitasking, @@ -8528,7 +8596,7 @@ else $as_nop lt_cv_sys_max_cmd_len=8192; ;; - bitrig* | darwin* | dragonfly* | freebsd* | netbsd* | openbsd*) + darwin* | dragonfly* | freebsd* | midnightbsd* | netbsd* | openbsd*) # This has been around since 386BSD, at least. Likely further. if test -x /sbin/sysctl; then lt_cv_sys_max_cmd_len=`/sbin/sysctl -n kern.argmax` @@ -8571,7 +8639,7 @@ else $as_nop sysv5* | sco5v6* | sysv4.2uw2*) kargmax=`grep ARG_MAX /etc/conf/cf.d/stune 2>/dev/null` if test -n "$kargmax"; then - lt_cv_sys_max_cmd_len=`echo $kargmax | sed 's/.*[ ]//'` + lt_cv_sys_max_cmd_len=`echo $kargmax | $SED 's/.*[ ]//'` else lt_cv_sys_max_cmd_len=32768 fi @@ -8670,7 +8738,7 @@ else $as_nop case $host in *-*-mingw* ) case $build in - *-*-mingw* ) # actually msys + *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_w32 ;; *-*-cygwin* ) @@ -8683,7 +8751,7 @@ else $as_nop ;; *-*-cygwin* ) case $build in - *-*-mingw* ) # actually msys + *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_host_file_cmd=func_convert_file_msys_to_cygwin ;; *-*-cygwin* ) @@ -8718,9 +8786,9 @@ else $as_nop #assume ordinary cross tools, or native build. lt_cv_to_tool_file_cmd=func_convert_file_noop case $host in - *-*-mingw* ) + *-*-mingw* | *-*-windows* ) case $build in - *-*-mingw* ) # actually msys + *-*-mingw* | *-*-windows* ) # actually msys lt_cv_to_tool_file_cmd=func_convert_file_msys_to_w32 ;; esac @@ -8754,7 +8822,7 @@ case $reload_flag in esac reload_cmds='$LD$reload_flag -o $output$reload_objs' case $host_os in - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) if test yes != "$GCC"; then reload_cmds=false fi @@ -8776,6 +8844,55 @@ esac +# Extract the first word of "file", so it can be a program name with args. +set dummy file; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_FILECMD+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$FILECMD"; then + ac_cv_prog_FILECMD="$FILECMD" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_FILECMD="file" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + + test -z "$ac_cv_prog_FILECMD" && ac_cv_prog_FILECMD=":" +fi +fi +FILECMD=$ac_cv_prog_FILECMD +if test -n "$FILECMD"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $FILECMD" >&5 +printf "%s\n" "$FILECMD" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + + + + + + + if test -n "$ac_tool_prefix"; then # Extract the first word of "${ac_tool_prefix}objdump", so it can be a program name with args. set dummy ${ac_tool_prefix}objdump; ac_word=$2 @@ -8902,7 +9019,6 @@ lt_cv_deplibs_check_method='unknown' # 'none' -- dependencies not supported. # 'unknown' -- same as none, but documents that we really don't know. # 'pass_all' -- all dependencies passed with no checks. -# 'test_compile' -- check by making test program. # 'file_magic [[regex]]' -- check by looking for files in library path # that responds to the $file_magic_cmd with a given extended regex. # If you have 'file' or equivalent on your system and you're not sure @@ -8919,7 +9035,7 @@ beos*) bsdi[45]*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (shared object|dynamic lib)' - lt_cv_file_magic_cmd='/usr/bin/file -L' + lt_cv_file_magic_cmd='$FILECMD -L' lt_cv_file_magic_test_file=/shlib/libc.so ;; @@ -8929,7 +9045,7 @@ cygwin*) lt_cv_file_magic_cmd='func_win32_libid' ;; -mingw* | pw32*) +mingw* | windows* | pw32*) # Base MSYS/MinGW do not provide the 'file' command needed by # func_win32_libid shell function, so use a weaker test based on 'objdump', # unless we find 'file', for example because we are cross-compiling. @@ -8938,7 +9054,7 @@ mingw* | pw32*) lt_cv_file_magic_cmd='func_win32_libid' else # Keep this pattern in sync with the one in func_win32_libid. - lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' + lt_cv_deplibs_check_method='file_magic file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64|pe-aarch64)' lt_cv_file_magic_cmd='$OBJDUMP -f' fi ;; @@ -8953,14 +9069,14 @@ darwin* | rhapsody*) lt_cv_deplibs_check_method=pass_all ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then case $host_cpu in i*86 ) # Not sure whether the presence of OpenBSD here was a mistake. # Let's accept both of them until this is cleared up. lt_cv_deplibs_check_method='file_magic (FreeBSD|OpenBSD|DragonFly)/i[3-9]86 (compact )?demand paged shared library' - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=`echo /usr/lib/libc.so.*` ;; esac @@ -8974,7 +9090,7 @@ haiku*) ;; hpux10.20* | hpux11*) - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD case $host_cpu in ia64*) lt_cv_deplibs_check_method='file_magic (s[0-9][0-9][0-9]|ELF-[0-9][0-9]) shared object file - IA64' @@ -9011,7 +9127,11 @@ linux* | k*bsd*-gnu | kopensolaris*-gnu lt_cv_deplibs_check_method=pass_all ;; -netbsd*) +*-mlibc) + lt_cv_deplibs_check_method=pass_all + ;; + +netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ > /dev/null; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|_pic\.a)$' else @@ -9021,7 +9141,7 @@ netbsd*) newos6*) lt_cv_deplibs_check_method='file_magic ELF [0-9][0-9]*-bit [ML]SB (executable|dynamic lib)' - lt_cv_file_magic_cmd=/usr/bin/file + lt_cv_file_magic_cmd=$FILECMD lt_cv_file_magic_test_file=/usr/lib/libnls.so ;; @@ -9029,7 +9149,7 @@ newos6*) lt_cv_deplibs_check_method=pass_all ;; -openbsd* | bitrig*) +openbsd*) if test -z "`echo __ELF__ | $CC -E - | $GREP __ELF__`"; then lt_cv_deplibs_check_method='match_pattern /lib[^/]+(\.so\.[0-9]+\.[0-9]+|\.so|_pic\.a)$' else @@ -9045,6 +9165,10 @@ rdos*) lt_cv_deplibs_check_method=pass_all ;; +serenity*) + lt_cv_deplibs_check_method=pass_all + ;; + solaris*) lt_cv_deplibs_check_method=pass_all ;; @@ -9096,7 +9220,7 @@ file_magic_glob= want_nocaseglob=no if test "$build" = "$host"; then case $host_os in - mingw* | pw32*) + mingw* | windows* | pw32*) if ( shopt | grep nocaseglob ) >/dev/null 2>&1; then want_nocaseglob=yes else @@ -9253,7 +9377,7 @@ else $as_nop lt_cv_sharedlib_from_linklib_cmd='unknown' case $host_os in -cygwin* | mingw* | pw32* | cegcc*) +cygwin* | mingw* | windows* | pw32* | cegcc*) # two different shell functions defined in ltmain.sh; # decide which one to use based on capabilities of $DLLTOOL case `$DLLTOOL --help 2>&1` in @@ -9284,6 +9408,108 @@ test -z "$sharedlib_from_linklib_cmd" && if test -n "$ac_tool_prefix"; then + # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. +set dummy ${ac_tool_prefix}ranlib; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_RANLIB+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$RANLIB"; then + ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +RANLIB=$ac_cv_prog_RANLIB +if test -n "$RANLIB"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 +printf "%s\n" "$RANLIB" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + +fi +if test -z "$ac_cv_prog_RANLIB"; then + ac_ct_RANLIB=$RANLIB + # Extract the first word of "ranlib", so it can be a program name with args. +set dummy ranlib; ac_word=$2 +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 +printf %s "checking for $ac_word... " >&6; } +if test ${ac_cv_prog_ac_ct_RANLIB+y} +then : + printf %s "(cached) " >&6 +else $as_nop + if test -n "$ac_ct_RANLIB"; then + ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. +else +as_save_IFS=$IFS; IFS=$PATH_SEPARATOR +for as_dir in $PATH +do + IFS=$as_save_IFS + case $as_dir in #((( + '') as_dir=./ ;; + */) ;; + *) as_dir=$as_dir/ ;; + esac + for ac_exec_ext in '' $ac_executable_extensions; do + if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then + ac_cv_prog_ac_ct_RANLIB="ranlib" + printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 + break 2 + fi +done + done +IFS=$as_save_IFS + +fi +fi +ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB +if test -n "$ac_ct_RANLIB"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 +printf "%s\n" "$ac_ct_RANLIB" >&6; } +else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +fi + + if test "x$ac_ct_RANLIB" = x; then + RANLIB=":" + else + case $cross_compiling:$ac_tool_warned in +yes:) +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 +printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} +ac_tool_warned=yes ;; +esac + RANLIB=$ac_ct_RANLIB + fi +else + RANLIB="$ac_cv_prog_RANLIB" +fi + +if test -n "$ac_tool_prefix"; then for ac_prog in ar do # Extract the first word of "$ac_tool_prefix$ac_prog", so it can be a program name with args. @@ -9394,13 +9620,29 @@ esac fi : ${AR=ar} -: ${AR_FLAGS=cru} +# Use ARFLAGS variable as AR's operation code to sync the variable naming with +# Automake. If both AR_FLAGS and ARFLAGS are specified, AR_FLAGS should have +# higher priority because that's what people were doing historically (setting +# ARFLAGS for automake and AR_FLAGS for libtool). FIXME: Make the AR_FLAGS +# variable obsoleted/removed. + +test ${AR_FLAGS+y} || AR_FLAGS=${ARFLAGS-cr} +lt_ar_flags=$AR_FLAGS + + + + + + +# Make AR_FLAGS overridable by 'make ARFLAGS='. Don't try to run-time override +# by AR_FLAGS because that was never working and AR_FLAGS is about to die. + @@ -9575,130 +9817,22 @@ test -z "$STRIP" && STRIP=: -if test -n "$ac_tool_prefix"; then - # Extract the first word of "${ac_tool_prefix}ranlib", so it can be a program name with args. -set dummy ${ac_tool_prefix}ranlib; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_RANLIB+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$RANLIB"; then - ac_cv_prog_RANLIB="$RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_RANLIB="${ac_tool_prefix}ranlib" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS -fi -fi -RANLIB=$ac_cv_prog_RANLIB +test -z "$RANLIB" && RANLIB=: + + + + + + +# Determine commands to create old-style static archives. +old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' +old_postinstall_cmds='chmod 644 $oldlib' +old_postuninstall_cmds= + if test -n "$RANLIB"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $RANLIB" >&5 -printf "%s\n" "$RANLIB" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - -fi -if test -z "$ac_cv_prog_RANLIB"; then - ac_ct_RANLIB=$RANLIB - # Extract the first word of "ranlib", so it can be a program name with args. -set dummy ranlib; ac_word=$2 -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $ac_word" >&5 -printf %s "checking for $ac_word... " >&6; } -if test ${ac_cv_prog_ac_ct_RANLIB+y} -then : - printf %s "(cached) " >&6 -else $as_nop - if test -n "$ac_ct_RANLIB"; then - ac_cv_prog_ac_ct_RANLIB="$ac_ct_RANLIB" # Let the user override the test. -else -as_save_IFS=$IFS; IFS=$PATH_SEPARATOR -for as_dir in $PATH -do - IFS=$as_save_IFS - case $as_dir in #((( - '') as_dir=./ ;; - */) ;; - *) as_dir=$as_dir/ ;; - esac - for ac_exec_ext in '' $ac_executable_extensions; do - if as_fn_executable_p "$as_dir$ac_word$ac_exec_ext"; then - ac_cv_prog_ac_ct_RANLIB="ranlib" - printf "%s\n" "$as_me:${as_lineno-$LINENO}: found $as_dir$ac_word$ac_exec_ext" >&5 - break 2 - fi -done - done -IFS=$as_save_IFS - -fi -fi -ac_ct_RANLIB=$ac_cv_prog_ac_ct_RANLIB -if test -n "$ac_ct_RANLIB"; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_ct_RANLIB" >&5 -printf "%s\n" "$ac_ct_RANLIB" >&6; } -else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } -fi - - if test "x$ac_ct_RANLIB" = x; then - RANLIB=":" - else - case $cross_compiling:$ac_tool_warned in -yes:) -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: WARNING: using cross tools not prefixed with host triplet" >&5 -printf "%s\n" "$as_me: WARNING: using cross tools not prefixed with host triplet" >&2;} -ac_tool_warned=yes ;; -esac - RANLIB=$ac_ct_RANLIB - fi -else - RANLIB="$ac_cv_prog_RANLIB" -fi - -test -z "$RANLIB" && RANLIB=: - - - - - - -# Determine commands to create old-style static archives. -old_archive_cmds='$AR $AR_FLAGS $oldlib$oldobjs' -old_postinstall_cmds='chmod 644 $oldlib' -old_postuninstall_cmds= - -if test -n "$RANLIB"; then - case $host_os in - bitrig* | openbsd*) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB -t \$tool_oldlib" - ;; - *) - old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" - ;; - esac - old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" + old_archive_cmds="$old_archive_cmds~\$RANLIB \$tool_oldlib" + old_postinstall_cmds="$old_postinstall_cmds~\$RANLIB \$tool_oldlib" fi case $host_os in @@ -9825,7 +9959,7 @@ case $host_os in aix*) symcode='[BCDT]' ;; -cygwin* | mingw* | pw32* | cegcc*) +cygwin* | mingw* | windows* | pw32* | cegcc*) symcode='[ABCDGISTW]' ;; hpux*) @@ -9840,7 +9974,7 @@ osf*) symcode='[BCDEGQRST]' ;; solaris*) - symcode='[BDRT]' + symcode='[BCDRT]' ;; sco3.2v5*) symcode='[DT]' @@ -9864,7 +9998,7 @@ esac if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Gets list of data symbols to import. - lt_cv_sys_global_symbol_to_import="sed -n -e 's/^I .* \(.*\)$/\1/p'" + lt_cv_sys_global_symbol_to_import="$SED -n -e 's/^I .* \(.*\)$/\1/p'" # Adjust the below global symbol transforms to fixup imported variables. lt_cdecl_hook=" -e 's/^I .* \(.*\)$/extern __declspec(dllimport) char \1;/p'" lt_c_name_hook=" -e 's/^I .* \(.*\)$/ {\"\1\", (void *) 0},/p'" @@ -9882,20 +10016,20 @@ fi # Transform an extracted symbol line into a proper C declaration. # Some systems (esp. on ia64) link data and code symbols differently, # so use this general approach. -lt_cv_sys_global_symbol_to_cdecl="sed -n"\ +lt_cv_sys_global_symbol_to_cdecl="$SED -n"\ $lt_cdecl_hook\ " -e 's/^T .* \(.*\)$/extern int \1();/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/extern char \1;/p'" # Transform an extracted symbol line into symbol name and symbol address -lt_cv_sys_global_symbol_to_c_name_address="sed -n"\ +lt_cv_sys_global_symbol_to_c_name_address="$SED -n"\ $lt_c_name_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(.*\)$/ {\"\1\", (void *) \&\1},/p'" # Transform an extracted symbol line into symbol name with lib prefix and # symbol address. -lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="sed -n"\ +lt_cv_sys_global_symbol_to_c_name_address_lib_prefix="$SED -n"\ $lt_c_name_lib_hook\ " -e 's/^: \(.*\) .*$/ {\"\1\", (void *) 0},/p'"\ " -e 's/^$symcode$symcode* .* \(lib.*\)$/ {\"\1\", (void *) \&\1},/p'"\ @@ -9904,7 +10038,7 @@ $lt_c_name_lib_hook\ # Handle CRLF in mingw tool chain opt_cr= case $build_os in -mingw*) +mingw* | windows*) opt_cr=`$ECHO 'x\{0,1\}' | tr x '\015'` # option cr in regexp ;; esac @@ -9919,7 +10053,7 @@ for ac_symprfx in "" "_"; do if test "$lt_cv_nm_interface" = "MS dumpbin"; then # Fake it for dumpbin and say T for any non-static function, # D for any global variable and I for any imported variable. - # Also find C++ and __fastcall symbols from MSVC++, + # Also find C++ and __fastcall symbols from MSVC++ or ICC, # which start with @ or ?. lt_cv_sys_global_symbol_pipe="$AWK '"\ " {last_section=section; section=\$ 3};"\ @@ -9937,9 +10071,9 @@ for ac_symprfx in "" "_"; do " s[1]~prfx {split(s[1],t,\"@\"); print f,t[1],substr(t[1],length(prfx))}"\ " ' prfx=^$ac_symprfx" else - lt_cv_sys_global_symbol_pipe="sed -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" + lt_cv_sys_global_symbol_pipe="$SED -n -e 's/^.*[ ]\($symcode$symcode*\)[ ][ ]*$ac_symprfx$sympat$opt_cr$/$symxfrm/p'" fi - lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | sed '/ __gnu_lto/d'" + lt_cv_sys_global_symbol_pipe="$lt_cv_sys_global_symbol_pipe | $SED '/ __gnu_lto/d'" # Check to see that the pipe works correctly. pipe_works=no @@ -9955,7 +10089,7 @@ void nm_test_func(void){} #ifdef __cplusplus } #endif -int main(){nm_test_var='a';nm_test_func();return(0);} +int main(void){nm_test_var='a';nm_test_func();return(0);} _LT_EOF if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$ac_compile\""; } >&5 @@ -9965,11 +10099,8 @@ _LT_EOF test $ac_status = 0; }; then # Now try to grab the symbols. nlist=conftest.nm - if { { eval echo "\"\$as_me\":${as_lineno-$LINENO}: \"$NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist\""; } >&5 - (eval $NM conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist) 2>&5 - ac_status=$? - printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 - test $ac_status = 0; } && test -s "$nlist"; then + $ECHO "$as_me:$LINENO: $NM conftest.$ac_objext | $lt_cv_sys_global_symbol_pipe > $nlist" >&5 + if eval "$NM" conftest.$ac_objext \| "$lt_cv_sys_global_symbol_pipe" \> $nlist 2>&5 && test -s "$nlist"; then # Try sorting and uniquifying the output. if sort "$nlist" | uniq > "$nlist"T; then mv -f "$nlist"T "$nlist" @@ -10138,11 +10269,13 @@ lt_sysroot= case $with_sysroot in #( yes) if test yes = "$GCC"; then - lt_sysroot=`$CC --print-sysroot 2>/dev/null` + # Trim trailing / since we'll always append absolute paths and we want + # to avoid //, if only for less confusing output for the user. + lt_sysroot=`$CC --print-sysroot 2>/dev/null | $SED 's:/\+$::'` fi ;; #( /*) - lt_sysroot=`echo "$with_sysroot" | sed -e "$sed_quote_subst"` + lt_sysroot=`echo "$with_sysroot" | $SED -e "$sed_quote_subst"` ;; #( no|'') ;; #( @@ -10267,7 +10400,7 @@ ia64-*-hpux*) ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *ELF-32*) HPUX_IA64_MODE=32 ;; @@ -10288,7 +10421,7 @@ ia64-*-hpux*) printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then if test yes = "$lt_cv_prog_gnu_ld"; then - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -melf32bsmip" ;; @@ -10300,7 +10433,7 @@ ia64-*-hpux*) ;; esac else - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) LD="${LD-ld} -32" ;; @@ -10326,7 +10459,7 @@ mips64*-*linux*) printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then emul=elf - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *32-bit*) emul="${emul}32" ;; @@ -10334,7 +10467,7 @@ mips64*-*linux*) emul="${emul}64" ;; esac - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *MSB*) emul="${emul}btsmip" ;; @@ -10342,7 +10475,7 @@ mips64*-*linux*) emul="${emul}ltsmip" ;; esac - case `/usr/bin/file conftest.$ac_objext` in + case `$FILECMD conftest.$ac_objext` in *N32*) emul="${emul}n32" ;; @@ -10353,7 +10486,7 @@ mips64*-*linux*) ;; x86_64-*kfreebsd*-gnu|x86_64-*linux*|powerpc*-*linux*| \ -s390*-*linux*|s390*-*tpf*|sparc*-*linux*) +s390*-*linux*|s390*-*tpf*|sparc*-*linux*|x86_64-gnu*) # Find out what ABI is being produced by ac_compile, and set linker # options accordingly. Note that the listed cases only cover the # situations where additional linker options are needed (such as when @@ -10366,14 +10499,14 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux* ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *32-bit*) case $host in x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_i386_fbsd" ;; - x86_64-*linux*) - case `/usr/bin/file conftest.o` in + x86_64-*linux*|x86_64-gnu*) + case `$FILECMD conftest.o` in *x86-64*) LD="${LD-ld} -m elf32_x86_64" ;; @@ -10401,7 +10534,7 @@ s390*-*linux*|s390*-*tpf*|sparc*-*linux* x86_64-*kfreebsd*-gnu) LD="${LD-ld} -m elf_x86_64_fbsd" ;; - x86_64-*linux*) + x86_64-*linux*|x86_64-gnu*) LD="${LD-ld} -m elf_x86_64" ;; powerpcle-*linux*) @@ -10481,7 +10614,7 @@ printf "%s\n" "$lt_cv_cc_needs_belf" >&6 ac_status=$? printf "%s\n" "$as_me:${as_lineno-$LINENO}: \$? = $ac_status" >&5 test $ac_status = 0; }; then - case `/usr/bin/file conftest.o` in + case `$FILECMD conftest.o` in *64-bit*) case $lt_cv_prog_gnu_ld in yes*) @@ -10618,22 +10751,22 @@ fi test -z "$MANIFEST_TOOL" && MANIFEST_TOOL=mt { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $MANIFEST_TOOL is a manifest tool" >&5 printf %s "checking if $MANIFEST_TOOL is a manifest tool... " >&6; } -if test ${lt_cv_path_mainfest_tool+y} +if test ${lt_cv_path_manifest_tool+y} then : printf %s "(cached) " >&6 else $as_nop - lt_cv_path_mainfest_tool=no + lt_cv_path_manifest_tool=no echo "$as_me:$LINENO: $MANIFEST_TOOL '-?'" >&5 $MANIFEST_TOOL '-?' 2>conftest.err > conftest.out cat conftest.err >&5 if $GREP 'Manifest Tool' conftest.out > /dev/null; then - lt_cv_path_mainfest_tool=yes + lt_cv_path_manifest_tool=yes fi rm -f conftest* fi -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_mainfest_tool" >&5 -printf "%s\n" "$lt_cv_path_mainfest_tool" >&6; } -if test yes != "$lt_cv_path_mainfest_tool"; then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_path_manifest_tool" >&5 +printf "%s\n" "$lt_cv_path_manifest_tool" >&6; } +if test yes != "$lt_cv_path_manifest_tool"; then MANIFEST_TOOL=: fi @@ -11217,6 +11350,43 @@ fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_apple_cc_single_mod" >&5 printf "%s\n" "$lt_cv_apple_cc_single_mod" >&6; } + # Feature test to disable chained fixups since it is not + # compatible with '-undefined dynamic_lookup' + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -no_fixup_chains linker flag" >&5 +printf %s "checking for -no_fixup_chains linker flag... " >&6; } +if test ${lt_cv_support_no_fixup_chains+y} +then : + printf %s "(cached) " >&6 +else $as_nop + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS -Wl,-no_fixup_chains" + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +int +main (void) +{ + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_link "$LINENO" +then : + lt_cv_support_no_fixup_chains=yes +else $as_nop + lt_cv_support_no_fixup_chains=no + +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam \ + conftest$ac_exeext conftest.$ac_ext + LDFLAGS=$save_LDFLAGS + + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_support_no_fixup_chains" >&5 +printf "%s\n" "$lt_cv_support_no_fixup_chains" >&6; } + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for -exported_symbols_list linker flag" >&5 printf %s "checking for -exported_symbols_list linker flag... " >&6; } if test ${lt_cv_ld_exported_symbols_list+y} @@ -11264,12 +11434,12 @@ int forced_loaded() { return 2;} _LT_EOF echo "$LTCC $LTCFLAGS -c -o conftest.o conftest.c" >&5 $LTCC $LTCFLAGS -c -o conftest.o conftest.c 2>&5 - echo "$AR cru libconftest.a conftest.o" >&5 - $AR cru libconftest.a conftest.o 2>&5 + echo "$AR $AR_FLAGS libconftest.a conftest.o" >&5 + $AR $AR_FLAGS libconftest.a conftest.o 2>&5 echo "$RANLIB libconftest.a" >&5 $RANLIB libconftest.a 2>&5 cat > conftest.c << _LT_EOF -int main() { return 0;} +int main(void) { return 0;} _LT_EOF echo "$LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a" >&5 $LTCC $LTCFLAGS $LDFLAGS -o conftest conftest.c -Wl,-force_load,./libconftest.a 2>conftest.err @@ -11292,23 +11462,37 @@ printf "%s\n" "$lt_cv_ld_force_load" >&6 _lt_dar_allow_undefined='$wl-undefined ${wl}suppress' ;; darwin1.*) _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - darwin*) # darwin 5.x on - # if running on 10.5 or later, the deployment target defaults - # to the OS version, if on x86, and 10.4, the deployment - # target defaults to 10.4. Don't you love it? - case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in - 10.0,*86*-darwin8*|10.0,*-darwin[91]*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; - 10.[012][,.]*) - _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; - 10.*) - _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' ;; + darwin*) + case $MACOSX_DEPLOYMENT_TARGET,$host in + 10.[012],*|,*powerpc*-darwin[5-8]*) + _lt_dar_allow_undefined='$wl-flat_namespace $wl-undefined ${wl}suppress' ;; + *) + _lt_dar_allow_undefined='$wl-undefined ${wl}dynamic_lookup' + if test yes = "$lt_cv_support_no_fixup_chains"; then + as_fn_append _lt_dar_allow_undefined ' $wl-no_fixup_chains' + fi + ;; esac ;; esac if test yes = "$lt_cv_apple_cc_single_mod"; then _lt_dar_single_mod='$single_module' fi + _lt_dar_needs_single_mod=no + case $host_os in + rhapsody* | darwin1.*) + _lt_dar_needs_single_mod=yes ;; + darwin*) + # When targeting Mac OS X 10.4 (darwin 8) or later, + # -single_module is the default and -multi_module is unsupported. + # The toolchain on macOS 10.14 (darwin 18) and later cannot + # target any OS version that needs -single_module. + case ${MACOSX_DEPLOYMENT_TARGET-10.0},$host in + 10.0,*-darwin[567].*|10.[0-3],*-darwin[5-9].*|10.[0-3],*-darwin1[0-7].*) + _lt_dar_needs_single_mod=yes ;; + esac + ;; + esac if test yes = "$lt_cv_ld_exported_symbols_list"; then _lt_dar_export_syms=' $wl-exported_symbols_list,$output_objdir/$libname-symbols.expsym' else @@ -11445,31 +11629,53 @@ fi - -# Check whether --with-pic was given. + # Check whether --enable-pic was given. +if test ${enable_pic+y} +then : + enableval=$enable_pic; lt_p=${PACKAGE-default} + case $enableval in + yes|no) pic_mode=$enableval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $enableval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac +else $as_nop + # Check whether --with-pic was given. if test ${with_pic+y} then : withval=$with_pic; lt_p=${PACKAGE-default} - case $withval in - yes|no) pic_mode=$withval ;; - *) - pic_mode=default - # Look at the argument we got. We use all the common list separators. - lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, - for lt_pkg in $withval; do - IFS=$lt_save_ifs - if test "X$lt_pkg" = "X$lt_p"; then - pic_mode=yes - fi - done - IFS=$lt_save_ifs - ;; - esac + case $withval in + yes|no) pic_mode=$withval ;; + *) + pic_mode=default + # Look at the argument we got. We use all the common list separators. + lt_save_ifs=$IFS; IFS=$IFS$PATH_SEPARATOR, + for lt_pkg in $withval; do + IFS=$lt_save_ifs + if test "X$lt_pkg" = "X$lt_p"; then + pic_mode=yes + fi + done + IFS=$lt_save_ifs + ;; + esac else $as_nop pic_mode=default fi +fi + + @@ -11512,18 +11718,29 @@ case $host,$enable_shared in power*-*-aix[5-9]*,yes) { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking which variant of shared library versioning to provide" >&5 printf %s "checking which variant of shared library versioning to provide... " >&6; } - -# Check whether --with-aix-soname was given. + # Check whether --enable-aix-soname was given. +if test ${enable_aix_soname+y} +then : + enableval=$enable_aix_soname; case $enableval in + aix|svr4|both) + ;; + *) + as_fn_error $? "Unknown argument to --enable-aix-soname" "$LINENO" 5 + ;; + esac + lt_cv_with_aix_soname=$enable_aix_soname +else $as_nop + # Check whether --with-aix-soname was given. if test ${with_aix_soname+y} then : withval=$with_aix_soname; case $withval in - aix|svr4|both) - ;; - *) - as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 - ;; - esac - lt_cv_with_aix_soname=$with_aix_soname + aix|svr4|both) + ;; + *) + as_fn_error $? "Unknown argument to --with-aix-soname" "$LINENO" 5 + ;; + esac + lt_cv_with_aix_soname=$with_aix_soname else $as_nop if test ${lt_cv_with_aix_soname+y} then : @@ -11532,9 +11749,12 @@ else $as_nop lt_cv_with_aix_soname=aix fi - with_aix_soname=$lt_cv_with_aix_soname fi + enable_aix_soname=$lt_cv_with_aix_soname +fi + + with_aix_soname=$enable_aix_soname { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $with_aix_soname" >&5 printf "%s\n" "$with_aix_soname" >&6; } if test aix != "$with_aix_soname"; then @@ -11663,8 +11883,8 @@ esac ofile=libtool can_build_shared=yes -# All known linkers require a '.a' archive for static linking (except MSVC, -# which needs '.lib'). +# All known linkers require a '.a' archive for static linking (except MSVC and +# ICC, which need '.lib'). libext=a with_gnu_ld=$lt_cv_prog_gnu_ld @@ -11847,7 +12067,7 @@ objext=$objext lt_simple_compile_test_code="int some_variable = 0;" # Code to be used in simple link tests -lt_simple_link_test_code='int main(){return(0);}' +lt_simple_link_test_code='int main(void){return(0);}' @@ -11984,7 +12204,7 @@ lt_prog_compiler_static= # PIC is the default for these OSes. ;; - mingw* | cygwin* | pw32* | os2* | cegcc*) + mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). # Although the cygwin gcc ignores -fPIC, still need this for old-style @@ -12087,7 +12307,7 @@ lt_prog_compiler_static= esac ;; - mingw* | cygwin* | pw32* | os2* | cegcc*) + mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) # This hack is so that the source file can tell whether it is being # built for inclusion in a dll (and should export symbols for example). lt_prog_compiler_pic='-DDLL_EXPORT' @@ -12128,6 +12348,12 @@ lt_prog_compiler_static= lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-static' ;; + *flang* | ftn | f18* | f95*) + # Flang compiler. + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; # icc used to be incompatible with GCC. # ICC 10 doesn't accept -KPIC any more. icc* | ifort*) @@ -12172,7 +12398,7 @@ lt_prog_compiler_static= lt_prog_compiler_static='-qstaticlink' ;; *) - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) # Sun Fortran 8.3 passes all unrecognized flags to the linker lt_prog_compiler_pic='-KPIC' @@ -12210,6 +12436,12 @@ lt_prog_compiler_static= lt_prog_compiler_static='-Bstatic' ;; + *-mlibc) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *nto* | *qnx*) # QNX uses GNU C++, but need to define -shared option too, otherwise # it will coredump. @@ -12226,6 +12458,9 @@ lt_prog_compiler_static= lt_prog_compiler_static='-non_shared' ;; + serenity*) + ;; + solaris*) lt_prog_compiler_pic='-KPIC' lt_prog_compiler_static='-Bstatic' @@ -12594,21 +12829,18 @@ printf %s "checking whether the $compile extract_expsyms_cmds= case $host_os in - cygwin* | mingw* | pw32* | cegcc*) - # FIXME: the MSVC++ port hasn't been tested in a loooong time + cygwin* | mingw* | windows* | pw32* | cegcc*) + # FIXME: the MSVC++ and ICC port hasn't been tested in a loooong time # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. if test yes != "$GCC"; then with_gnu_ld=no fi ;; interix*) - # we just hope/assume this is gcc and not c89 (= MSVC++) + # we just hope/assume this is gcc and not c89 (= MSVC++ or ICC) with_gnu_ld=yes ;; - openbsd* | bitrig*) - with_gnu_ld=no - ;; esac ld_shlibs=yes @@ -12655,7 +12887,7 @@ printf %s "checking whether the $compile whole_archive_flag_spec= fi supports_anon_versioning=no - case `$LD -v | $SED -e 's/(^)\+)\s\+//' 2>&1` in + case `$LD -v | $SED -e 's/([^)]\+)\s\+//' 2>&1` in *GNU\ gold*) supports_anon_versioning=yes ;; *\ [01].* | *\ 2.[0-9].* | *\ 2.10.*) ;; # catch versions < 2.11 *\ 2.11.93.0.2\ *) supports_anon_versioning=yes ;; # RH7.3 ... @@ -12709,7 +12941,7 @@ _LT_EOF fi ;; - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) # _LT_TAGVAR(hardcode_libdir_flag_spec, ) is actually meaningless, # as there is no search path for DLLs. hardcode_libdir_flag_spec='-L$libdir' @@ -12719,6 +12951,7 @@ _LT_EOF enable_shared_with_static_runtimes=yes export_symbols_cmds='$NM $libobjs $convenience | $global_symbol_pipe | $SED -e '\''/^[BCDGRS][ ]/s/.*[ ]\([^ ]*\)/\1 DATA/;s/^.*[ ]__nm__\([^ ]*\)[ ][^ ]*/\1 DATA/;/^I[ ]/d;/^[AITW][ ]/s/.* //'\'' | sort | uniq > $export_symbols' exclude_expsyms='[_]+GLOBAL_OFFSET_TABLE_|[_]+GLOBAL__[FID]_.*|[_]+head_[A-Za-z0-9_]+_dll|[A-Za-z0-9_]+_dll_iname' + file_list_spec='@' if $LD --help 2>&1 | $GREP 'auto-import' > /dev/null; then archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags -o $output_objdir/$soname $wl--enable-auto-image-base -Xlinker --out-implib -Xlinker $lib' @@ -12738,7 +12971,7 @@ _LT_EOF haiku*) archive_cmds='$CC -shared $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' - link_all_deplibs=yes + link_all_deplibs=no ;; os2*) @@ -12765,8 +12998,9 @@ _LT_EOF cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' - old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes + file_list_spec='@' ;; interix[3-9]*) @@ -12781,7 +13015,7 @@ _LT_EOF # 256 KiB-aligned image base between 0x50000000 and 0x6FFC0000 at link # time. Moving up from 0x10000000 also allows more sbrk(2) space. archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' - archive_expsym_cmds='sed "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' + archive_expsym_cmds='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-h,$soname $wl--retain-symbols-file,$output_objdir/$soname.expsym $wl--image-base,`expr ${RANDOM-$$} % 4096 / 2 \* 262144 + 1342177280` -o $lib' ;; gnu* | linux* | tpf* | k*bsd*-gnu | kopensolaris*-gnu) @@ -12824,7 +13058,7 @@ _LT_EOF compiler_needs_object=yes ;; esac - case `$CC -V 2>&1 | sed 5q` in + case `$CC -V 2>&1 | $SED 5q` in *Sun\ C*) # Sun C 5.9 whole_archive_flag_spec='$wl--whole-archive`new_convenience=; for conv in $convenience\"\"; do test -z \"$conv\" || new_convenience=\"$new_convenience,$conv\"; done; func_echo_all \"$new_convenience\"` $wl--no-whole-archive' compiler_needs_object=yes @@ -12836,13 +13070,14 @@ _LT_EOF if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $CC '"$tmp_sharedflag""$tmp_addflag"' $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-version-script $wl$output_objdir/$libname.ver -o $lib' fi case $cc_basename in tcc*) + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' export_dynamic_flag_spec='-rdynamic' ;; xlf* | bgf* | bgxlf* | mpixlf*) @@ -12852,7 +13087,7 @@ _LT_EOF archive_cmds='$LD -shared $libobjs $deplibs $linker_flags -soname $soname -o $lib' if test yes = "$supports_anon_versioning"; then archive_expsym_cmds='echo "{ global:" > $output_objdir/$libname.ver~ - cat $export_symbols | sed -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ + cat $export_symbols | $SED -e "s/\(.*\)/\1;/" >> $output_objdir/$libname.ver~ echo "local: *; };" >> $output_objdir/$libname.ver~ $LD -shared $libobjs $deplibs $linker_flags -soname $soname -version-script $output_objdir/$libname.ver -o $lib' fi @@ -12863,7 +13098,12 @@ _LT_EOF fi ;; - netbsd*) + *-mlibc) + archive_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname -o $lib' + archive_expsym_cmds='$CC -shared $pic_flag $libobjs $deplibs $compiler_flags $wl-soname $wl$soname $wl-retain-symbols-file $wl$export_symbols -o $lib' + ;; + + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable $libobjs $deplibs $linker_flags -o $lib' wlarc= @@ -12984,7 +13224,7 @@ _LT_EOF if $NM -V 2>&1 | $GREP 'GNU' > /dev/null; then export_symbols_cmds='$NM -Bpg $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W")) && (substr(\$ 3,1,1) != ".")) { if (\$ 2 == "W") { print \$ 3 " weak" } else { print \$ 3 } } }'\'' | sort -u > $export_symbols' else - export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' + export_symbols_cmds='`func_echo_all $NM | $SED -e '\''s/B\([^B]*\)$/P\1/'\''` -PCpgl $libobjs $convenience | awk '\''{ if (((\$ 2 == "T") || (\$ 2 == "D") || (\$ 2 == "B") || (\$ 2 == "L") || (\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) && (substr(\$ 1,1,1) != ".")) { if ((\$ 2 == "W") || (\$ 2 == "V") || (\$ 2 == "Z")) { print \$ 1 " weak" } else { print \$ 1 } } }'\'' | sort -u > $export_symbols' fi aix_use_runtimelinking=no @@ -13253,14 +13493,14 @@ fi export_dynamic_flag_spec=-rdynamic ;; - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) # When not using gcc, we currently assume that we are using - # Microsoft Visual C++. + # Microsoft Visual C++ or Intel C++ Compiler. # hardcode_libdir_flag_spec is actually meaningless, as there is # no search path for DLLs. case $cc_basename in - cl*) - # Native MSVC + cl* | icl*) + # Native MSVC or ICC hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported always_export_symbols=yes @@ -13270,14 +13510,14 @@ fi # Tell ltmain to make .dll files, not .so files. shrext_cmds=.dll # FIXME: Setting linknames here is a bad hack. - archive_cmds='$CC -o $output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' + archive_cmds='$CC -Fe$output_objdir/$soname $libobjs $compiler_flags $deplibs -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~linknames=' archive_expsym_cmds='if test DEF = "`$SED -n -e '\''s/^[ ]*//'\'' -e '\''/^\(;.*\)*$/d'\'' -e '\''s/^\(EXPORTS\|LIBRARY\)\([ ].*\)*$/DEF/p'\'' -e q $export_symbols`" ; then cp "$export_symbols" "$output_objdir/$soname.def"; echo "$tool_output_objdir$soname.def" > "$output_objdir/$soname.exp"; else $SED -e '\''s/^/-link -EXPORT:/'\'' < $export_symbols > $output_objdir/$soname.exp; fi~ - $CC -o $tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ + $CC -Fe$tool_output_objdir$soname $libobjs $compiler_flags $deplibs "@$tool_output_objdir$soname.exp" -Wl,-DLL,-IMPLIB:"$tool_output_objdir$libname.dll.lib"~ linknames=' # The linker will not automatically build a static lib if we build a DLL. # _LT_TAGVAR(old_archive_from_new_cmds, )='true' @@ -13301,7 +13541,7 @@ fi fi' ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper hardcode_libdir_flag_spec=' ' allow_undefined_flag=unsupported # Tell ltmain to make .lib files, not .a files. @@ -13342,8 +13582,8 @@ fi output_verbose_link_cmd=func_echo_all archive_cmds="\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dsymutil" module_cmds="\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dsymutil" - archive_expsym_cmds="sed 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" - module_expsym_cmds="sed -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" + archive_expsym_cmds="$SED 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC -dynamiclib \$allow_undefined_flag -o \$lib \$libobjs \$deplibs \$compiler_flags -install_name \$rpath/\$soname \$verstring $_lt_dar_single_mod$_lt_dar_export_syms$_lt_dsymutil" + module_expsym_cmds="$SED -e 's|^|_|' < \$export_symbols > \$output_objdir/\$libname-symbols.expsym~\$CC \$allow_undefined_flag -o \$lib -bundle \$libobjs \$deplibs \$compiler_flags$_lt_dar_export_syms$_lt_dsymutil" else ld_shlibs=no @@ -13377,7 +13617,7 @@ fi ;; # FreeBSD 3 and greater uses gcc -shared to do shared libraries. - freebsd* | dragonfly*) + freebsd* | dragonfly* | midnightbsd*) archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' hardcode_libdir_flag_spec='-R$libdir' hardcode_direct=yes @@ -13557,11 +13797,15 @@ printf "%s\n" "$lt_cv_irix_exported_symb # Fabrice Bellard et al's Tiny C Compiler ld_shlibs=yes archive_cmds='$CC -shared $pic_flag -o $lib $libobjs $deplibs $compiler_flags' + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' ;; esac ;; - netbsd*) + *-mlibc) + ;; + + netbsd* | netbsdelf*-gnu) if echo __ELF__ | $CC -E - | $GREP __ELF__ >/dev/null; then archive_cmds='$LD -Bshareable -o $lib $libobjs $deplibs $linker_flags' # a.out else @@ -13583,7 +13827,7 @@ printf "%s\n" "$lt_cv_irix_exported_symb *nto* | *qnx*) ;; - openbsd* | bitrig*) + openbsd*) if test -f /usr/libexec/ld.so; then hardcode_direct=yes hardcode_shlibpath_var=no @@ -13626,8 +13870,9 @@ printf "%s\n" "$lt_cv_irix_exported_symb cat $export_symbols | $prefix_cmds >> $output_objdir/$libname.def~ $CC -Zdll -Zcrtdll -o $output_objdir/$soname $libobjs $deplibs $compiler_flags $output_objdir/$libname.def~ emximp -o $lib $output_objdir/$libname.def' - old_archive_From_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' + old_archive_from_new_cmds='emximp -o $output_objdir/${libname}_dll.a $output_objdir/$libname.def' enable_shared_with_static_runtimes=yes + file_list_spec='@' ;; osf3*) @@ -13661,6 +13906,9 @@ printf "%s\n" "$lt_cv_irix_exported_symb hardcode_libdir_separator=: ;; + serenity*) + ;; + solaris*) no_undefined_flag=' -z defs' if test yes = "$GCC"; then @@ -14066,7 +14314,7 @@ if test yes = "$GCC"; then *) lt_awk_arg='/^libraries:/' ;; esac case $host_os in - mingw* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; + mingw* | windows* | cegcc*) lt_sed_strip_eq='s|=\([A-Za-z]:\)|\1|g' ;; *) lt_sed_strip_eq='s|=/|/|g' ;; esac lt_search_path_spec=`$CC -print-search-dirs | awk $lt_awk_arg | $SED -e "s/^libraries://" -e $lt_sed_strip_eq` @@ -14124,7 +14372,7 @@ BEGIN {RS = " "; FS = "/|\n";} { # AWK program above erroneously prepends '/' to C:/dos/paths # for these hosts. case $host_os in - mingw* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ + mingw* | windows* | cegcc*) lt_search_path_spec=`$ECHO "$lt_search_path_spec" |\ $SED 's|/\([A-Za-z]:\)|\1|g'` ;; esac sys_lib_search_path_spec=`$ECHO "$lt_search_path_spec" | $lt_NL2SP` @@ -14198,7 +14446,7 @@ aix[4-9]*) # Unfortunately, runtime linking may impact performance, so we do # not want this to be the default eventually. Also, we use the # versioned .so libs for executables only if there is the -brtl - # linker flag in LDFLAGS as well, or --with-aix-soname=svr4 only. + # linker flag in LDFLAGS as well, or --enable-aix-soname=svr4 only. # To allow for filename-based versioning support, we need to create # libNAME.so.V as an archive file, containing: # *) an Import File, referring to the versioned filename of the @@ -14292,7 +14540,7 @@ bsdi[45]*) # libtool to hard-code these into programs ;; -cygwin* | mingw* | pw32* | cegcc*) +cygwin* | mingw* | windows* | pw32* | cegcc*) version_type=windows shrext_cmds=.dll need_version=no @@ -14303,15 +14551,29 @@ cygwin* | mingw* | pw32* | cegcc*) # gcc library_names_spec='$libname.dll.a' # DLL is installed to $(libdir)/../bin by postinstall_cmds - postinstall_cmds='base_file=`basename \$file`~ - dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ - dldir=$destdir/`dirname \$dlpath`~ - test -d \$dldir || mkdir -p \$dldir~ - $install_prog $dir/$dlname \$dldir/$dlname~ - chmod a+x \$dldir/$dlname~ - if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then - eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; - fi' + # If user builds GCC with multilib enabled, + # it should just install on $(libdir) + # not on $(libdir)/../bin or 32 bits dlls would override 64 bit ones. + if test xyes = x"$multilib"; then + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + $install_prog $dir/$dlname $destdir/$dlname~ + chmod a+x $destdir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib $destdir/$dlname'\'' || exit \$?; + fi' + else + postinstall_cmds='base_file=`basename \$file`~ + dlpath=`$SHELL 2>&1 -c '\''. $dir/'\''\$base_file'\''i; echo \$dlname'\''`~ + dldir=$destdir/`dirname \$dlpath`~ + test -d \$dldir || mkdir -p \$dldir~ + $install_prog $dir/$dlname \$dldir/$dlname~ + chmod a+x \$dldir/$dlname~ + if test -n '\''$stripme'\'' && test -n '\''$striplib'\''; then + eval '\''$striplib \$dldir/$dlname'\'' || exit \$?; + fi' + fi postuninstall_cmds='dldll=`$SHELL 2>&1 -c '\''. $file; echo \$dlname'\''`~ dlpath=$dir/\$dldll~ $RM \$dlpath' @@ -14320,30 +14582,30 @@ cygwin* | mingw* | pw32* | cegcc*) case $host_os in cygwin*) # Cygwin DLLs use 'cyg' prefix rather than 'lib' - soname_spec='`echo $libname | sed -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + soname_spec='`echo $libname | $SED -e 's/^lib/cyg/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' sys_lib_search_path_spec="$sys_lib_search_path_spec /usr/lib/w32api" ;; - mingw* | cegcc*) + mingw* | windows* | cegcc*) # MinGW DLLs use traditional 'lib' prefix soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; pw32*) # pw32 DLLs use 'pw' prefix rather than 'lib' - library_names_spec='`echo $libname | sed -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' + library_names_spec='`echo $libname | $SED -e 's/^lib/pw/'``echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' ;; esac dynamic_linker='Win32 ld.exe' ;; - *,cl*) - # Native MSVC + *,cl* | *,icl*) + # Native MSVC or ICC libname_spec='$name' soname_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext' library_names_spec='$libname.dll.lib' case $build_os in - mingw*) + mingw* | windows*) sys_lib_search_path_spec= lt_save_ifs=$IFS IFS=';' @@ -14356,7 +14618,7 @@ cygwin* | mingw* | pw32* | cegcc*) done IFS=$lt_save_ifs # Convert to MSYS style. - sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | sed -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` + sys_lib_search_path_spec=`$ECHO "$sys_lib_search_path_spec" | $SED -e 's|\\\\|/|g' -e 's| \\([a-zA-Z]\\):| /\\1|g' -e 's|^ ||'` ;; cygwin*) # Convert to unix form, then to dos form, then back to unix form @@ -14393,7 +14655,7 @@ cygwin* | mingw* | pw32* | cegcc*) ;; *) - # Assume MSVC wrapper + # Assume MSVC and ICC wrapper library_names_spec='$libname`echo $release | $SED -e 's/[.]/-/g'`$versuffix$shared_ext $libname.lib' dynamic_linker='Win32 ld.exe' ;; @@ -14426,7 +14688,7 @@ dgux*) shlibpath_var=LD_LIBRARY_PATH ;; -freebsd* | dragonfly*) +freebsd* | dragonfly* | midnightbsd*) # DragonFly does not have aout. When/if they implement a new # versioning mechanism, adjust this. if test -x /usr/bin/objformat; then @@ -14450,7 +14712,27 @@ freebsd* | dragonfly*) need_version=yes ;; esac + case $host_cpu in + powerpc64) + # On FreeBSD bi-arch platforms, a different variable is used for 32-bit + # binaries. See . + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +int test_pointer_size[sizeof (void *) - 5]; + +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : shlibpath_var=LD_LIBRARY_PATH +else $as_nop + shlibpath_var=LD_32_LIBRARY_PATH +fi +rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ;; + *) + shlibpath_var=LD_LIBRARY_PATH + ;; + esac case $host_os in freebsd2.*) shlibpath_overrides_runpath=yes @@ -14480,8 +14762,9 @@ haiku*) soname_spec='$libname$release$shared_ext$major' shlibpath_var=LIBRARY_PATH shlibpath_overrides_runpath=no - sys_lib_dlsearch_path_spec='/boot/home/config/lib /boot/common/lib /boot/system/lib' - hardcode_into_libs=yes + sys_lib_search_path_spec='/boot/system/non-packaged/develop/lib /boot/system/develop/lib' + sys_lib_dlsearch_path_spec='/boot/home/config/non-packaged/lib /boot/home/config/lib /boot/system/non-packaged/lib /boot/system/lib' + hardcode_into_libs=no ;; hpux9* | hpux10* | hpux11*) @@ -14591,7 +14874,7 @@ linux*android*) version_type=none # Android doesn't support versioned libraries. need_lib_prefix=no need_version=no - library_names_spec='$libname$release$shared_ext' + library_names_spec='$libname$release$shared_ext $libname$shared_ext' soname_spec='$libname$release$shared_ext' finish_cmds= shlibpath_var=LD_LIBRARY_PATH @@ -14603,8 +14886,9 @@ linux*android*) hardcode_into_libs=yes dynamic_linker='Android linker' - # Don't embed -rpath directories since the linker doesn't support them. - hardcode_libdir_flag_spec='-L$libdir' + # -rpath works at least for libraries that are not overridden by + # libraries installed in system locations. + hardcode_libdir_flag_spec='$wl-rpath $wl$libdir' ;; # This must be glibc/ELF. @@ -14663,7 +14947,7 @@ fi # Add ABI-specific directories to the system library path. sys_lib_dlsearch_path_spec="/lib64 /usr/lib64 /lib /usr/lib" - # Ideally, we could use ldconfig to report *all* directores which are + # Ideally, we could use ldconfig to report *all* directories which are # searched for libraries, however this is still not possible. Aside from not # being certain /sbin/ldconfig is available, command # 'ldconfig -N -X -v | grep ^/' on 64bit Fedora does not report /usr/lib64, @@ -14683,6 +14967,18 @@ fi dynamic_linker='GNU/Linux ld.so' ;; +netbsdelf*-gnu) + version_type=linux + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + dynamic_linker='NetBSD ld.elf_so' + ;; + netbsd*) version_type=sunos need_lib_prefix=no @@ -14701,6 +14997,18 @@ netbsd*) hardcode_into_libs=yes ;; +*-mlibc) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + dynamic_linker='mlibc ld.so' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + hardcode_into_libs=yes + ;; + newsos6) version_type=linux # correct to gnu/linux during the next big refactor library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' @@ -14720,7 +15028,7 @@ newsos6) dynamic_linker='ldqnx.so' ;; -openbsd* | bitrig*) +openbsd*) version_type=sunos sys_lib_dlsearch_path_spec=/usr/lib need_lib_prefix=no @@ -14780,6 +15088,17 @@ rdos*) dynamic_linker=no ;; +serenity*) + version_type=linux # correct to gnu/linux during the next big refactor + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext$versuffix $libname$release$shared_ext$major $libname$shared_ext' + soname_spec='$libname$release$shared_ext$major' + shlibpath_var=LD_LIBRARY_PATH + shlibpath_overrides_runpath=no + dynamic_linker='SerenityOS LibELF' + ;; + solaris*) version_type=linux # correct to gnu/linux during the next big refactor need_lib_prefix=no @@ -14877,29 +15196,516 @@ uts4*) shlibpath_var=LD_LIBRARY_PATH ;; -*) - dynamic_linker=no - ;; -esac -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 -printf "%s\n" "$dynamic_linker" >&6; } -test no = "$dynamic_linker" && can_build_shared=no - -variables_saved_for_relink="PATH $shlibpath_var $runpath_var" -if test yes = "$GCC"; then - variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" -fi +emscripten*) + version_type=none + need_lib_prefix=no + need_version=no + library_names_spec='$libname$release$shared_ext' + soname_spec='$libname$release$shared_ext' + finish_cmds= + dynamic_linker="Emscripten linker" + lt_prog_compiler_wl= +lt_prog_compiler_pic= +lt_prog_compiler_static= -if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then - sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec -fi -if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then - sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec -fi + if test yes = "$GCC"; then + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_static='-static' -# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... -configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec + case $host_os in + aix*) + # All AIX code is PIC. + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + fi + lt_prog_compiler_pic='-fPIC' + ;; + + amigaos*) + case $host_cpu in + powerpc) + # see comment about AmigaOS4 .so support + lt_prog_compiler_pic='-fPIC' + ;; + m68k) + # FIXME: we need at least 68020 code to build shared libraries, but + # adding the '-m68020' flag to GCC prevents building anything better, + # like '-m68040'. + lt_prog_compiler_pic='-m68020 -resident32 -malways-restore-a4' + ;; + esac + ;; + + beos* | irix5* | irix6* | nonstopux* | osf3* | osf4* | osf5*) + # PIC is the default for these OSes. + ;; + + mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + # Although the cygwin gcc ignores -fPIC, still need this for old-style + # (--disable-auto-import) libraries + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + ;; + + haiku*) + # PIC is the default for Haiku. + # The "-static" flag exists, but is broken. + lt_prog_compiler_static= + ;; + + hpux*) + # PIC is the default for 64-bit PA HP-UX, but not for 32-bit + # PA HP-UX. On IA64 HP-UX, PIC is the default but the pic flag + # sets the default TLS model and affects inlining. + case $host_cpu in + hppa*64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + ;; + + interix[3-9]*) + # Interix 3.x gcc -fpic/-fPIC options generate broken code. + # Instead, we relocate shared libraries at runtime. + ;; + + msdosdjgpp*) + # Just because we use GCC doesn't mean we suddenly get shared libraries + # on systems that don't support them. + lt_prog_compiler_can_build_shared=no + enable_shared=no + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic=-Kconform_pic + fi + ;; + + *) + lt_prog_compiler_pic='-fPIC' + ;; + esac + + case $cc_basename in + nvcc*) # Cuda Compiler Driver 2.2 + lt_prog_compiler_wl='-Xlinker ' + if test -n "$lt_prog_compiler_pic"; then + lt_prog_compiler_pic="-Xcompiler $lt_prog_compiler_pic" + fi + ;; + esac + else + # PORTME Check for flag to pass linker flags through the system compiler. + case $host_os in + aix*) + lt_prog_compiler_wl='-Wl,' + if test ia64 = "$host_cpu"; then + # AIX 5 now supports IA64 processor + lt_prog_compiler_static='-Bstatic' + else + lt_prog_compiler_static='-bnso -bI:/lib/syscalls.exp' + fi + ;; + + darwin* | rhapsody*) + # PIC is the default on this platform + # Common symbols not allowed in MH_DYLIB files + lt_prog_compiler_pic='-fno-common' + case $cc_basename in + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + + mingw* | windows* | cygwin* | pw32* | os2* | cegcc*) + # This hack is so that the source file can tell whether it is being + # built for inclusion in a dll (and should export symbols for example). + lt_prog_compiler_pic='-DDLL_EXPORT' + case $host_os in + os2*) + lt_prog_compiler_static='$wl-static' + ;; + esac + ;; + + hpux9* | hpux10* | hpux11*) + lt_prog_compiler_wl='-Wl,' + # PIC is the default for IA64 HP-UX and 64-bit HP-UX, but + # not for PA HP-UX. + case $host_cpu in + hppa*64*|ia64*) + # +Z the default + ;; + *) + lt_prog_compiler_pic='+Z' + ;; + esac + # Is there a better lt_prog_compiler_static that works with the bundled CC? + lt_prog_compiler_static='$wl-a ${wl}archive' + ;; + + irix5* | irix6* | nonstopux*) + lt_prog_compiler_wl='-Wl,' + # PIC (with -KPIC) is the default. + lt_prog_compiler_static='-non_shared' + ;; + + linux* | k*bsd*-gnu | kopensolaris*-gnu | gnu*) + case $cc_basename in + # old Intel for x86_64, which still supported -KPIC. + ecc*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-static' + ;; + *flang* | ftn | f18* | f95*) + # Flang compiler. + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # icc used to be incompatible with GCC. + # ICC 10 doesn't accept -KPIC any more. + icc* | ifort*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + # Lahey Fortran 8.1. + lf95*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='--shared' + lt_prog_compiler_static='--static' + ;; + nagfor*) + # NAG Fortran compiler + lt_prog_compiler_wl='-Wl,-Wl,,' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + tcc*) + # Fabrice Bellard et al's Tiny C Compiler + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + pgcc* | pgf77* | pgf90* | pgf95* | pgfortran*) + # Portland Group compilers (*not* the Pentium gcc compiler, + # which looks to be a dead project) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + ccc*) + lt_prog_compiler_wl='-Wl,' + # All Alpha code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + xl* | bgxl* | bgf* | mpixl*) + # IBM XL C 8.0/Fortran 10.1, 11.1 on PPC and BlueGene + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-qpic' + lt_prog_compiler_static='-qstaticlink' + ;; + *) + case `$CC -V 2>&1 | $SED 5q` in + *Sun\ Ceres\ Fortran* | *Sun*Fortran*\ [1-7].* | *Sun*Fortran*\ 8.[0-3]*) + # Sun Fortran 8.3 passes all unrecognized flags to the linker + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='' + ;; + *Sun\ F* | *Sun*Fortran*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Qoption ld ' + ;; + *Sun\ C*) + # Sun C 5.9 + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + lt_prog_compiler_wl='-Wl,' + ;; + *Intel*\ [CF]*Compiler*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + *Portland\ Group*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fpic' + lt_prog_compiler_static='-Bstatic' + ;; + esac + ;; + esac + ;; + + newsos6) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + *-mlibc) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-fPIC' + lt_prog_compiler_static='-static' + ;; + + *nto* | *qnx*) + # QNX uses GNU C++, but need to define -shared option too, otherwise + # it will coredump. + lt_prog_compiler_pic='-fPIC -shared' + ;; + + osf3* | osf4* | osf5*) + lt_prog_compiler_wl='-Wl,' + # All OSF/1 code is PIC. + lt_prog_compiler_static='-non_shared' + ;; + + rdos*) + lt_prog_compiler_static='-non_shared' + ;; + + serenity*) + ;; + + solaris*) + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + case $cc_basename in + f77* | f90* | f95* | sunf77* | sunf90* | sunf95*) + lt_prog_compiler_wl='-Qoption ld ';; + *) + lt_prog_compiler_wl='-Wl,';; + esac + ;; + + sunos4*) + lt_prog_compiler_wl='-Qoption ld ' + lt_prog_compiler_pic='-PIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4 | sysv4.2uw2* | sysv4.3*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + sysv4*MP*) + if test -d /usr/nec; then + lt_prog_compiler_pic='-Kconform_pic' + lt_prog_compiler_static='-Bstatic' + fi + ;; + + sysv5* | unixware* | sco3.2v5* | sco5v6* | OpenUNIX*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_pic='-KPIC' + lt_prog_compiler_static='-Bstatic' + ;; + + unicos*) + lt_prog_compiler_wl='-Wl,' + lt_prog_compiler_can_build_shared=no + ;; + + uts4*) + lt_prog_compiler_pic='-pic' + lt_prog_compiler_static='-Bstatic' + ;; + + *) + lt_prog_compiler_can_build_shared=no + ;; + esac + fi + +case $host_os in + # For platforms that do not support PIC, -DPIC is meaningless: + *djgpp*) + lt_prog_compiler_pic= + ;; + *) + lt_prog_compiler_pic="$lt_prog_compiler_pic -DPIC" + ;; +esac + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for $compiler option to produce PIC" >&5 +printf %s "checking for $compiler option to produce PIC... " >&6; } +if test ${lt_cv_prog_compiler_pic+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_pic=$lt_prog_compiler_pic +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic" >&6; } +lt_prog_compiler_pic=$lt_cv_prog_compiler_pic + +# +# Check to make sure the PIC flag actually works. +# +if test -n "$lt_prog_compiler_pic"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler PIC flag $lt_prog_compiler_pic works" >&5 +printf %s "checking if $compiler PIC flag $lt_prog_compiler_pic works... " >&6; } +if test ${lt_cv_prog_compiler_pic_works+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_pic_works=no + ac_outfile=conftest.$ac_objext + echo "$lt_simple_compile_test_code" > conftest.$ac_ext + lt_compiler_flag="$lt_prog_compiler_pic -DPIC" ## exclude from sc_useless_quotes_in_assignment + # Insert the option either (1) after the last *FLAGS variable, or + # (2) before a word containing "conftest.", or (3) at the end. + # Note that $ac_compile itself does not contain backslashes and begins + # with a dollar sign (not a hyphen), so the echo should work correctly. + # The option is referenced via a variable to avoid confusing sed. + lt_compile=`echo "$ac_compile" | $SED \ + -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \ + -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \ + -e 's:$: $lt_compiler_flag:'` + (eval echo "\"\$as_me:$LINENO: $lt_compile\"" >&5) + (eval "$lt_compile" 2>conftest.err) + ac_status=$? + cat conftest.err >&5 + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + if (exit $ac_status) && test -s "$ac_outfile"; then + # The compiler can only warn and ignore the option if not recognized + # So say no if there are warnings other than the usual output. + $ECHO "$_lt_compiler_boilerplate" | $SED '/^$/d' >conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if test ! -s conftest.er2 || diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_pic_works=yes + fi + fi + $RM conftest* + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_pic_works" >&5 +printf "%s\n" "$lt_cv_prog_compiler_pic_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_pic_works"; then + case $lt_prog_compiler_pic in + "" | " "*) ;; + *) lt_prog_compiler_pic=" $lt_prog_compiler_pic" ;; + esac +else + lt_prog_compiler_pic= + lt_prog_compiler_can_build_shared=no +fi + +fi + + + + + +# +# Check to make sure the static flag actually works. +# +wl=$lt_prog_compiler_wl eval lt_tmp_static_flag=\"$lt_prog_compiler_static\" +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if $compiler static flag $lt_tmp_static_flag works" >&5 +printf %s "checking if $compiler static flag $lt_tmp_static_flag works... " >&6; } +if test ${lt_cv_prog_compiler_static_works+y} +then : + printf %s "(cached) " >&6 +else $as_nop + lt_cv_prog_compiler_static_works=no + save_LDFLAGS=$LDFLAGS + LDFLAGS="$LDFLAGS $lt_tmp_static_flag" + echo "$lt_simple_link_test_code" > conftest.$ac_ext + if (eval $ac_link 2>conftest.err) && test -s conftest$ac_exeext; then + # The linker can only warn and ignore the option if not recognized + # So say no if there are warnings + if test -s conftest.err; then + # Append any errors to the config.log. + cat conftest.err 1>&5 + $ECHO "$_lt_linker_boilerplate" | $SED '/^$/d' > conftest.exp + $SED '/^$/d; /^ *+/d' conftest.err >conftest.er2 + if diff conftest.exp conftest.er2 >/dev/null; then + lt_cv_prog_compiler_static_works=yes + fi + else + lt_cv_prog_compiler_static_works=yes + fi + fi + $RM -r conftest* + LDFLAGS=$save_LDFLAGS + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $lt_cv_prog_compiler_static_works" >&5 +printf "%s\n" "$lt_cv_prog_compiler_static_works" >&6; } + +if test yes = "$lt_cv_prog_compiler_static_works"; then + : +else + lt_prog_compiler_static= +fi + + + +='-fPIC' + archive_cmds='$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib' + archive_expsym_cmds='$SED "s|^|_|" $export_symbols >$output_objdir/$soname.expsym~$CC -sSIDE_MODULE=2 -shared $libobjs $deplibs $compiler_flags -o $lib -s EXPORTED_FUNCTIONS=@$output_objdir/$soname.expsym' + archive_cmds_need_lc=no + no_undefined_flag= + ;; + +*) + dynamic_linker=no + ;; +esac +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $dynamic_linker" >&5 +printf "%s\n" "$dynamic_linker" >&6; } +test no = "$dynamic_linker" && can_build_shared=no + +variables_saved_for_relink="PATH $shlibpath_var $runpath_var" +if test yes = "$GCC"; then + variables_saved_for_relink="$variables_saved_for_relink GCC_EXEC_PREFIX COMPILER_PATH LIBRARY_PATH" +fi + +if test set = "${lt_cv_sys_lib_search_path_spec+set}"; then + sys_lib_search_path_spec=$lt_cv_sys_lib_search_path_spec +fi + +if test set = "${lt_cv_sys_lib_dlsearch_path_spec+set}"; then + sys_lib_dlsearch_path_spec=$lt_cv_sys_lib_dlsearch_path_spec +fi + +# remember unaugmented sys_lib_dlsearch_path content for libtool script decls... +configure_time_dlsearch_path=$sys_lib_dlsearch_path_spec # ... but it needs LT_SYS_LIBRARY_PATH munging for other configure-time code func_munge_path_list sys_lib_dlsearch_path_spec "$LT_SYS_LIBRARY_PATH" @@ -15061,7 +15867,7 @@ else lt_cv_dlopen_self=yes ;; - mingw* | pw32* | cegcc*) + mingw* | windows* | pw32* | cegcc*) lt_cv_dlopen=LoadLibrary lt_cv_dlopen_libs= ;; @@ -15388,11 +16194,11 @@ else /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); +int fnord (void) __attribute__((visibility("default"))); #endif -int fnord () { return 42; } -int main () +int fnord (void) { return 42; } +int main (void) { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; @@ -15495,11 +16301,11 @@ else /* When -fvisibility=hidden is used, assume the code has been annotated correspondingly for the symbols needed. */ #if defined __GNUC__ && (((__GNUC__ == 3) && (__GNUC_MINOR__ >= 3)) || (__GNUC__ > 3)) -int fnord () __attribute__((visibility("default"))); +int fnord (void) __attribute__((visibility("default"))); #endif -int fnord () { return 42; } -int main () +int fnord (void) { return 42; } +int main (void) { void *self = dlopen (0, LT_DLGLOBAL|LT_DLLAZY_OR_NOW); int status = $lt_dlunknown; @@ -15582,30 +16388,41 @@ striplib= old_striplib= { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether stripping libraries is possible" >&5 printf %s "checking whether stripping libraries is possible... " >&6; } -if test -n "$STRIP" && $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then - test -z "$old_striplib" && old_striplib="$STRIP --strip-debug" - test -z "$striplib" && striplib="$STRIP --strip-unneeded" - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } +if test -z "$STRIP"; then + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } else -# FIXME - insert some real tests, host_os isn't really good enough - case $host_os in - darwin*) - if test -n "$STRIP"; then + if $STRIP -V 2>&1 | $GREP "GNU strip" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + else + case $host_os in + darwin*) + # FIXME - insert some real tests, host_os isn't really good enough striplib="$STRIP -x" old_striplib="$STRIP -S" { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - else - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + ;; + freebsd*) + if $STRIP -V 2>&1 | $GREP "elftoolchain" >/dev/null; then + old_striplib="$STRIP --strip-debug" + striplib="$STRIP --strip-unneeded" + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + else + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - fi - ;; - *) - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + fi + ;; + *) + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - ;; - esac + ;; + esac + fi fi @@ -15828,6 +16645,9 @@ printf "%s\n" "no" >&6; } PKG_CONFIG="" fi fi +if test -z "$PKG_CONFIG"; then + as_fn_error $? "pkg-config not found" "$LINENO" 5 +fi fi # Checks for header files. @@ -15943,6 +16763,13 @@ then : printf "%s\n" "#define HAVE_GLOB_H 1" >>confdefs.h fi +ac_fn_c_check_header_compile "$LINENO" "fnmatch.h" "ac_cv_header_fnmatch_h" "$ac_includes_default +" +if test "x$ac_cv_header_fnmatch_h" = xyes +then : + printf "%s\n" "#define HAVE_FNMATCH_H 1" >>confdefs.h + +fi ac_fn_c_check_header_compile "$LINENO" "grp.h" "ac_cv_header_grp_h" "$ac_includes_default " if test "x$ac_cv_header_grp_h" = xyes @@ -17729,8 +18556,8 @@ then : have_systemd=no pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD" >&5 -printf %s "checking for SYSTEMD... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libsystemd" >&5 +printf %s "checking for libsystemd... " >&6; } if test -n "$SYSTEMD_CFLAGS"; then pkg_cv_SYSTEMD_CFLAGS="$SYSTEMD_CFLAGS" @@ -17770,7 +18597,7 @@ fi if test $pkg_failed = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -17779,14 +18606,14 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd" 2>&1` + SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd" 2>&1` else - SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd" 2>&1` + SYSTEMD_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$SYSTEMD_PKG_ERRORS" >&5 + # Put the nasty error message in config.log where it belongs + echo "$SYSTEMD_PKG_ERRORS" >&5 - as_fn_error $? "Package requirements (libsystemd) were not met: + as_fn_error $? "Package requirements (libsystemd) were not met: $SYSTEMD_PKG_ERRORS @@ -17797,9 +18624,9 @@ Alternatively, you may set the environme and SYSTEMD_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full @@ -17812,11 +18639,11 @@ See the pkg-config man page for more det To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else - SYSTEMD_CFLAGS=$pkg_cv_SYSTEMD_CFLAGS - SYSTEMD_LIBS=$pkg_cv_SYSTEMD_LIBS + SYSTEMD_CFLAGS=$pkg_cv_SYSTEMD_CFLAGS + SYSTEMD_LIBS=$pkg_cv_SYSTEMD_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - have_systemd=yes + have_systemd=yes fi if test "x$have_systemd" != "xyes" then : @@ -17824,8 +18651,8 @@ then : have_systemd_daemon=no pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for SYSTEMD_DAEMON" >&5 -printf %s "checking for SYSTEMD_DAEMON... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libsystemd-daemon" >&5 +printf %s "checking for libsystemd-daemon... " >&6; } if test -n "$SYSTEMD_DAEMON_CFLAGS"; then pkg_cv_SYSTEMD_DAEMON_CFLAGS="$SYSTEMD_DAEMON_CFLAGS" @@ -17865,7 +18692,7 @@ fi if test $pkg_failed = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -17874,14 +18701,14 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - SYSTEMD_DAEMON_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd-daemon" 2>&1` + SYSTEMD_DAEMON_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libsystemd-daemon" 2>&1` else - SYSTEMD_DAEMON_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd-daemon" 2>&1` + SYSTEMD_DAEMON_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libsystemd-daemon" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$SYSTEMD_DAEMON_PKG_ERRORS" >&5 + # Put the nasty error message in config.log where it belongs + echo "$SYSTEMD_DAEMON_PKG_ERRORS" >&5 - as_fn_error $? "Package requirements (libsystemd-daemon) were not met: + as_fn_error $? "Package requirements (libsystemd-daemon) were not met: $SYSTEMD_DAEMON_PKG_ERRORS @@ -17892,9 +18719,9 @@ Alternatively, you may set the environme and SYSTEMD_DAEMON_LIBS to avoid the need to call pkg-config. See the pkg-config man page for more details." "$LINENO" 5 elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } - { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 + { { printf "%s\n" "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 printf "%s\n" "$as_me: error: in \`$ac_pwd':" >&2;} as_fn_error $? "The pkg-config script could not be found or is too old. Make sure it is in your PATH or set the PKG_CONFIG environment variable to the full @@ -17907,11 +18734,11 @@ See the pkg-config man page for more det To get pkg-config, see . See \`config.log' for more details" "$LINENO" 5; } else - SYSTEMD_DAEMON_CFLAGS=$pkg_cv_SYSTEMD_DAEMON_CFLAGS - SYSTEMD_DAEMON_LIBS=$pkg_cv_SYSTEMD_DAEMON_LIBS + SYSTEMD_DAEMON_CFLAGS=$pkg_cv_SYSTEMD_DAEMON_CFLAGS + SYSTEMD_DAEMON_LIBS=$pkg_cv_SYSTEMD_DAEMON_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } - have_systemd_daemon=yes + have_systemd_daemon=yes fi if test "x$have_systemd_daemon" = "xyes" then : @@ -17972,7 +18799,9 @@ if test x_$enable_alloc_nonregional = x_ printf "%s\n" "#define UNBOUND_ALLOC_NONREGIONAL 1" >>confdefs.h fi -if test x_$enable_alloc_checks = x_yes; then +if test x_$enable_alloc_checks = x_yes +then : + printf "%s\n" "#define UNBOUND_ALLOC_STATS 1" >>confdefs.h @@ -17980,28 +18809,29 @@ printf "%s\n" "#define UNBOUND_ALLOC_STA ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ="alloc.lo" -else - if test x_$enable_alloc_lite = x_yes; then + +else $as_nop + + if test x_$enable_alloc_lite = x_yes +then : + printf "%s\n" "#define UNBOUND_ALLOC_LITE 1" >>confdefs.h - else + +else $as_nop + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for GNU libc compatible malloc" >&5 printf %s "checking for GNU libc compatible malloc... " >&6; } - if test "$cross_compiling" = yes +if test ${ac_cv_func_malloc_0_nonnull+y} then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no (crosscompile)" >&5 -printf "%s\n" "no (crosscompile)" >&6; } - case " $LIBOBJS " in - *" malloc.$ac_objext "* ) ;; - *) LIBOBJS="$LIBOBJS malloc.$ac_objext" - ;; -esac - - -printf "%s\n" "#define malloc rpl_malloc_unbound" >>confdefs.h + printf %s "(cached) " >&6 +else $as_nop + if test "$cross_compiling" = yes +then : + ac_cv_func_malloc_0_nonnull="no (crosscompile)" else $as_nop cat confdefs.h - <<_ACEOF >conftest.$ac_ext /* end confdefs.h. */ @@ -18022,9 +18852,26 @@ main (void) _ACEOF if ac_fn_c_try_run "$LINENO" then : - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 -printf "%s\n" "no" >&6; } - case " $LIBOBJS " in + ac_cv_func_malloc_0_nonnull=no +else $as_nop + ac_cv_func_malloc_0_nonnull=yes +fi +rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ + conftest.$ac_objext conftest.beam conftest.$ac_ext +fi + + +fi +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: $ac_cv_func_malloc_0_nonnull" >&5 +printf "%s\n" "$ac_cv_func_malloc_0_nonnull" >&6; } + if test "$ac_cv_func_malloc_0_nonnull" = yes +then : + +printf "%s\n" "#define HAVE_MALLOC 1" >>confdefs.h + +else $as_nop + + case " $LIBOBJS " in *" malloc.$ac_objext "* ) ;; *) LIBOBJS="$LIBOBJS malloc.$ac_objext" ;; @@ -18033,19 +18880,12 @@ esac printf "%s\n" "#define malloc rpl_malloc_unbound" >>confdefs.h -else $as_nop - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 -printf "%s\n" "yes" >&6; } - -printf "%s\n" "#define HAVE_MALLOC 1" >>confdefs.h fi -rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext \ - conftest.$ac_objext conftest.beam conftest.$ac_ext -fi - fi +fi + fi # check windows threads (we use them, not pthreads, on windows). @@ -18331,7 +19171,31 @@ fi # correctly enabled case $host_os in - darwin* | hpux* | linux* | osf* | solaris*) + solaris*) + # Solaris 11.4 introduced XPG7 support and did away with the need for + # _REENTRANT. + + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ + +# undef _XOPEN_SOURCE +# include +# if _XOPEN_VERSION < 700 + AX_PTHREAD_SOLARIS__REENTRANT +# endif + +_ACEOF +if (eval "$ac_cpp conftest.$ac_ext") 2>&5 | + $EGREP "AX_PTHREAD_SOLARIS__REENTRANT" >/dev/null 2>&1 +then : + ax_pthread_check_macro="_REENTRANT" +else $as_nop + ax_pthread_check_macro="--" +fi +rm -rf conftest* + + ;; + darwin* | hpux* | linux* | osf*) ax_pthread_check_macro="_REENTRANT" ;; @@ -19006,6 +19870,171 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu fi +if test x_$ub_have_pthreads != x_no; then + # Long checks to support pthread_setname_np(). + # Some OSes have the extra non-portable functions in a specific + # header file. + ac_fn_c_check_header_compile "$LINENO" "pthread_np.h" "ac_cv_header_pthread_np_h" "$ac_includes_default +" +if test "x$ac_cv_header_pthread_np_h" = xyes +then : + printf "%s\n" "#define HAVE_PTHREAD_NP_H 1" >>confdefs.h + +fi + + BAKCFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Werror" + # MacOS only has 1 argument, the name. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthread_setname_np has only 1 argument" >&5 +printf %s "checking whether pthread_setname_np has only 1 argument... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +#include +#ifdef HAVE_PTHREAD_NP_H +#include +#endif + +int +main (void) +{ + + (void)pthread_setname_np(""); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define HAVE_PTHREAD_SETNAME_NP1 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_ext + # NetBSD has 3 arguments to allow for formatting of the name. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthread_setname_np has 3 arguments" >&5 +printf %s "checking whether pthread_setname_np has 3 arguments... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +#include +#ifdef HAVE_PTHREAD_NP_H +#include +#endif + +int +main (void) +{ + + (void)pthread_setname_np(0, "", NULL); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define HAVE_PTHREAD_SETNAME_NP3 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_ext + # Most OSes have the common 2 arguments, thread and name. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthread_setname_np has the common 2 arguments" >&5 +printf %s "checking whether pthread_setname_np has the common 2 arguments... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +#include +#ifdef HAVE_PTHREAD_NP_H +#include +#endif + +int +main (void) +{ + + (void)pthread_setname_np(0, ""); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define HAVE_PTHREAD_SETNAME_NP 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_ext + # FreeBSD/OpenBSD use a slightly different function name. + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking whether pthread_setname_np exists as pthread_set_name_np instead" >&5 +printf %s "checking whether pthread_setname_np exists as pthread_set_name_np instead... " >&6; } + cat confdefs.h - <<_ACEOF >conftest.$ac_ext +/* end confdefs.h. */ +$ac_includes_default +#include +#ifdef HAVE_PTHREAD_NP_H +#include +#endif + +int +main (void) +{ + + (void)pthread_set_name_np(0, ""); + + ; + return 0; +} +_ACEOF +if ac_fn_c_try_compile "$LINENO" +then : + + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define HAVE_PTHREAD_SET_NAME_NP 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_ext + CFLAGS="$BAKCFLAGS" +fi + # check solaris thread library # Check whether --with-solaris-threads was given. @@ -20820,6 +21849,12 @@ then : printf "%s\n" "#define HAVE_BIO_SET_CALLBACK_EX 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "OPENSSL_cleanup" "ac_cv_func_OPENSSL_cleanup" +if test "x$ac_cv_func_OPENSSL_cleanup" = xyes +then : + printf "%s\n" "#define HAVE_OPENSSL_CLEANUP 1" >>confdefs.h + +fi # these check_funcs need -lssl @@ -20849,6 +21884,24 @@ then : printf "%s\n" "#define HAVE_SSL_GET0_PEERNAME 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "SSL_set1_dnsname" "ac_cv_func_SSL_set1_dnsname" +if test "x$ac_cv_func_SSL_set1_dnsname" = xyes +then : + printf "%s\n" "#define HAVE_SSL_SET1_DNSNAME 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "X509_get_key_usage" "ac_cv_func_X509_get_key_usage" +if test "x$ac_cv_func_X509_get_key_usage" = xyes +then : + printf "%s\n" "#define HAVE_X509_GET_KEY_USAGE 1" >>confdefs.h + +fi +ac_fn_c_check_func "$LINENO" "ASN1_STRING_get0_data" "ac_cv_func_ASN1_STRING_get0_data" +if test "x$ac_cv_func_ASN1_STRING_get0_data" = xyes +then : + printf "%s\n" "#define HAVE_ASN1_STRING_GET0_DATA 1" >>confdefs.h + +fi ac_fn_c_check_func "$LINENO" "X509_VERIFY_PARAM_set1_host" "ac_cv_func_X509_VERIFY_PARAM_set1_host" if test "x$ac_cv_func_X509_VERIFY_PARAM_set1_host" = xyes then : @@ -20892,6 +21945,54 @@ then : fi +ac_fn_c_check_func "$LINENO" "X509_NAME_get_text_by_NID" "ac_cv_func_X509_NAME_get_text_by_NID" +if test "x$ac_cv_func_X509_NAME_get_text_by_NID" = xyes +then : + printf "%s\n" "#define HAVE_X509_NAME_GET_TEXT_BY_NID 1" >>confdefs.h + +fi + +if test $ac_cv_func_X509_NAME_get_text_by_NID = yes; then + + +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if X509_NAME_get_text_by_NID is deprecated" >&5 +printf %s "checking if X509_NAME_get_text_by_NID is deprecated... " >&6; } +cache=`echo X509_NAME_get_text_by_NID | sed 'y%.=/+-%___p_%'` +if eval test \${cv_cc_deprecated_$cache+y} +then : + printf %s "(cached) " >&6 +else $as_nop + +echo ' +#include "openssl/x509.h" +' >conftest.c +echo 'void f(void){ + (void)X509_NAME_get_text_by_NID(NULL, 0, NULL, 0); }' >>conftest.c +if test -z "`$CC $CPPFLAGS $CFLAGS -c conftest.c 2>&1 | grep -e deprecated -e unavailable`"; then +eval "cv_cc_deprecated_$cache=no" +else +eval "cv_cc_deprecated_$cache=yes" +fi +rm -f conftest conftest.o conftest.c + +fi + +if eval "test \"`echo '$cv_cc_deprecated_'$cache`\" = yes"; then +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 +printf "%s\n" "yes" >&6; } + +printf "%s\n" "#define DEPRECATED_X509_NAME_GET_TEXT_BY_NID 1" >>confdefs.h + +: + +else +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 +printf "%s\n" "no" >&6; } +: + +fi + +fi LIBS="$BAKLIBS" ac_fn_check_decl "$LINENO" "SSL_COMP_get_compression_methods" "ac_cv_have_decl_SSL_COMP_get_compression_methods" " @@ -21458,7 +22559,7 @@ fi { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking if openssl supports SHA2 and ECDSA with EVP" >&5 printf %s "checking if openssl supports SHA2 and ECDSA with EVP... " >&6; } if grep OPENSSL_VERSION_TEXT $ssldir_include/openssl/opensslv.h | grep "OpenSSL" >/dev/null; then - if grep OPENSSL_VERSION_NUMBER $ssldir_include/openssl/opensslv.h | grep 0x0 >/dev/null; then + if grep OPENSSL_VERSION_TEXT $ssldir_include/openssl/opensslv.h | grep "OpenSSL 0\." >/dev/null; then { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } @@ -22398,6 +23499,24 @@ then : printf "%s\n" "#define USE_NGTCP2_CRYPTO_OSSL 1" >>confdefs.h + ac_fn_check_decl "$LINENO" "ngtcp2_crypto_ossl_ctx_new" "ac_cv_have_decl_ngtcp2_crypto_ossl_ctx_new" "$ac_includes_default + #include + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_ngtcp2_crypto_ossl_ctx_new" = xyes +then : + ac_have_decl=1 +else $as_nop + ac_have_decl=0 +fi +printf "%s\n" "#define HAVE_DECL_NGTCP2_CRYPTO_OSSL_CTX_NEW $ac_have_decl" >>confdefs.h +if test $ac_have_decl = 1 +then : + +else $as_nop + as_fn_error $? "No declaration of ngtcp2_crypto_ossl_ctx_new in the ngtcp2_crypto_ossl header file. Perhaps the ngtcp2_crypto_ossl devel header files need to be installed." "$LINENO" 5 +fi + else $as_nop @@ -22577,6 +23696,13 @@ else $as_nop fi done + ac_fn_c_check_func "$LINENO" "SSL_set_quic_tls_early_data_enabled" "ac_cv_func_SSL_set_quic_tls_early_data_enabled" +if test "x$ac_cv_func_SSL_set_quic_tls_early_data_enabled" = xyes +then : + printf "%s\n" "#define HAVE_SSL_SET_QUIC_TLS_EARLY_DATA_ENABLED 1" >>confdefs.h + +fi + LIBS="$BAKLIBS" ac_fn_c_check_type "$LINENO" "struct ngtcp2_version_cid" "ac_cv_type_struct_ngtcp2_version_cid" "$ac_includes_default @@ -22682,6 +23808,29 @@ printf "%s\n" "no" >&6; } fi rm -f core conftest.err conftest.$ac_objext conftest.beam conftest.$ac_ext + ac_fn_check_decl "$LINENO" "CLOCK_MONOTONIC + " "ac_cv_have_decl_CLOCK_MONOTONIC_________" "$ac_includes_default +#ifdef TIME_WITH_SYS_TIME +# include +# include +#else +# ifdef HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + +" "$ac_c_undeclared_builtin_options" "CFLAGS" +if test "x$ac_cv_have_decl_CLOCK_MONOTONIC_________" = xyes +then : + + +else $as_nop + as_fn_error $? "ngtcp2 for QUIC needs at least CLOCK_MONOTONIC on the system" "$LINENO" 5 + +fi + fi # set static linking for uninstalled libraries if requested @@ -22743,10 +23892,12 @@ then : LIBS="$LIBS -lz" fi - if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then - : - else - LIBS="$LIBS -l:libssp.a" + if echo "$host" | $GREP -i -e linux >/dev/null; then + if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then + : + else + LIBS="$LIBS -l:libssp.a" + fi fi fi fi @@ -22807,10 +23958,12 @@ then : LIBS="$LIBS -lz" fi - if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then - : - else - LIBS="$LIBS -l:libssp.a" + if echo "$host" | $GREP -i -e linux >/dev/null; then + if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then + : + else + LIBS="$LIBS -l:libssp.a" + fi fi fi fi @@ -23188,6 +24341,23 @@ fi fi +ac_fn_c_check_member "$LINENO" "struct stat" "st_mtimensec" "ac_cv_member_struct_stat_st_mtimensec" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_mtimensec" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STAT_ST_MTIMENSEC 1" >>confdefs.h + + +fi +ac_fn_c_check_member "$LINENO" "struct stat" "st_mtim.tv_nsec" "ac_cv_member_struct_stat_st_mtim_tv_nsec" "$ac_includes_default" +if test "x$ac_cv_member_struct_stat_st_mtim_tv_nsec" = xyes +then : + +printf "%s\n" "#define HAVE_STRUCT_STAT_ST_MTIM_TV_NSEC 1" >>confdefs.h + + +fi + ac_fn_c_check_member "$LINENO" "struct sockaddr_un" "sun_len" "ac_cv_member_struct_sockaddr_un_sun_len" " $ac_includes_default #ifdef HAVE_SYS_UN_H @@ -23496,6 +24666,12 @@ then : printf "%s\n" "#define HAVE_GLOB 1" >>confdefs.h fi +ac_fn_c_check_func "$LINENO" "fnmatch" "ac_cv_func_fnmatch" +if test "x$ac_cv_func_fnmatch" = xyes +then : + printf "%s\n" "#define HAVE_FNMATCH 1" >>confdefs.h + +fi ac_fn_c_check_func "$LINENO" "initgroups" "ac_cv_func_initgroups" if test "x$ac_cv_func_initgroups" = xyes then : @@ -24532,8 +25708,8 @@ else $as_nop if test -n "$PKG_CONFIG"; then pkg_failed=no -{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for PROTOBUFC" >&5 -printf %s "checking for PROTOBUFC... " >&6; } +{ printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for libprotobuf-c" >&5 +printf %s "checking for libprotobuf-c... " >&6; } if test -n "$PROTOBUFC_CFLAGS"; then pkg_cv_PROTOBUFC_CFLAGS="$PROTOBUFC_CFLAGS" @@ -24573,7 +25749,7 @@ fi if test $pkg_failed = yes; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } if $PKG_CONFIG --atleast-pkgconfig-version 0.20; then @@ -24582,12 +25758,12 @@ else _pkg_short_errors_supported=no fi if test $_pkg_short_errors_supported = yes; then - PROTOBUFC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libprotobuf-c" 2>&1` + PROTOBUFC_PKG_ERRORS=`$PKG_CONFIG --short-errors --print-errors --cflags --libs "libprotobuf-c" 2>&1` else - PROTOBUFC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libprotobuf-c" 2>&1` + PROTOBUFC_PKG_ERRORS=`$PKG_CONFIG --print-errors --cflags --libs "libprotobuf-c" 2>&1` fi - # Put the nasty error message in config.log where it belongs - echo "$PROTOBUFC_PKG_ERRORS" >&5 + # Put the nasty error message in config.log where it belongs + echo "$PROTOBUFC_PKG_ERRORS" >&5 # pkg-config failed; try falling back to known values @@ -24605,7 +25781,7 @@ fi elif test $pkg_failed = untried; then - { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 + { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: no" >&5 printf "%s\n" "no" >&6; } # pkg-config failed; try falling back to known values @@ -24623,8 +25799,8 @@ printf "%s\n" "no" >&6; } else - PROTOBUFC_CFLAGS=$pkg_cv_PROTOBUFC_CFLAGS - PROTOBUFC_LIBS=$pkg_cv_PROTOBUFC_LIBS + PROTOBUFC_CFLAGS=$pkg_cv_PROTOBUFC_CFLAGS + PROTOBUFC_LIBS=$pkg_cv_PROTOBUFC_LIBS { printf "%s\n" "$as_me:${as_lineno-$LINENO}: result: yes" >&5 printf "%s\n" "yes" >&6; } @@ -25291,7 +26467,7 @@ printf "%s\n" "#define MAXSYSLOGMSGLEN 1 -version=1.24.0 +version=1.26.1 { printf "%s\n" "$as_me:${as_lineno-$LINENO}: checking for build time" >&5 printf %s "checking for build time... " >&6; } @@ -25821,7 +26997,7 @@ cat >>$CONFIG_STATUS <<\_ACEOF || ac_wri # 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.24.0, which was +This file was extended by unbound $as_me 1.26.1, which was generated by GNU Autoconf 2.71. Invocation command line was CONFIG_FILES = $CONFIG_FILES @@ -25889,7 +27065,7 @@ ac_cs_config_escaped=`printf "%s\n" "$ac cat >>$CONFIG_STATUS <<_ACEOF || ac_write_fail=1 ac_cs_config='$ac_cs_config_escaped' ac_cs_version="\\ -unbound config.status 1.24.0 +unbound config.status 1.26.1 configured by $0, generated by GNU Autoconf 2.71, with options \\"\$ac_cs_config\\" @@ -26049,6 +27225,7 @@ lt_cv_to_host_file_cmd='`$ECHO "$lt_cv_t lt_cv_to_tool_file_cmd='`$ECHO "$lt_cv_to_tool_file_cmd" | $SED "$delay_single_quote_subst"`' reload_flag='`$ECHO "$reload_flag" | $SED "$delay_single_quote_subst"`' reload_cmds='`$ECHO "$reload_cmds" | $SED "$delay_single_quote_subst"`' +FILECMD='`$ECHO "$FILECMD" | $SED "$delay_single_quote_subst"`' OBJDUMP='`$ECHO "$OBJDUMP" | $SED "$delay_single_quote_subst"`' deplibs_check_method='`$ECHO "$deplibs_check_method" | $SED "$delay_single_quote_subst"`' file_magic_cmd='`$ECHO "$file_magic_cmd" | $SED "$delay_single_quote_subst"`' @@ -26057,6 +27234,7 @@ want_nocaseglob='`$ECHO "$want_nocaseglo DLLTOOL='`$ECHO "$DLLTOOL" | $SED "$delay_single_quote_subst"`' sharedlib_from_linklib_cmd='`$ECHO "$sharedlib_from_linklib_cmd" | $SED "$delay_single_quote_subst"`' AR='`$ECHO "$AR" | $SED "$delay_single_quote_subst"`' +lt_ar_flags='`$ECHO "$lt_ar_flags" | $SED "$delay_single_quote_subst"`' AR_FLAGS='`$ECHO "$AR_FLAGS" | $SED "$delay_single_quote_subst"`' archiver_list_spec='`$ECHO "$archiver_list_spec" | $SED "$delay_single_quote_subst"`' STRIP='`$ECHO "$STRIP" | $SED "$delay_single_quote_subst"`' @@ -26177,6 +27355,7 @@ LN_S \ lt_SP2NL \ lt_NL2SP \ reload_flag \ +FILECMD \ OBJDUMP \ deplibs_check_method \ file_magic_cmd \ @@ -26185,7 +27364,6 @@ want_nocaseglob \ DLLTOOL \ sharedlib_from_linklib_cmd \ AR \ -AR_FLAGS \ archiver_list_spec \ STRIP \ RANLIB \ @@ -26878,19 +28056,18 @@ printf "%s\n" "$as_me: executing $ac_fil cat <<_LT_EOF >> "$cfgfile" #! $SHELL # Generated automatically by $as_me ($PACKAGE) $VERSION -# Libtool was configured on host `(hostname || uname -n) 2>/dev/null | sed 1q`: # NOTE: Changes made to this file will be lost: look at ltmain.sh. # Provide generalized library-building support services. # Written by Gordon Matzigkeit, 1996 -# Copyright (C) 2014 Free Software Foundation, Inc. +# Copyright (C) 2024 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. # GNU Libtool 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 2 of of the License, or +# the Free Software Foundation; either version 2 of the License, or # (at your option) any later version. # # As a special exception to the GNU General Public License, if you @@ -26998,6 +28175,9 @@ to_host_file_cmd=$lt_cv_to_host_file_cmd # convert \$build files to toolchain format. to_tool_file_cmd=$lt_cv_to_tool_file_cmd +# A file(cmd) program that detects file types. +FILECMD=$lt_FILECMD + # An object symbol dumper. OBJDUMP=$lt_OBJDUMP @@ -27022,8 +28202,11 @@ sharedlib_from_linklib_cmd=$lt_sharedlib # The archiver. AR=$lt_AR +# Flags to create an archive (by configure). +lt_ar_flags=$lt_ar_flags + # Flags to create an archive. -AR_FLAGS=$lt_AR_FLAGS +AR_FLAGS=\${ARFLAGS-"\$lt_ar_flags"} # How to feed a file listing to the archiver. archiver_list_spec=$lt_archiver_list_spec @@ -27265,7 +28448,7 @@ hardcode_direct=$hardcode_direct # Set to "yes" if using DIR/libNAME\$shared_ext during linking hardcodes # DIR into the resulting binary and the resulting library dependency is -# "absolute",i.e impossible to change by setting \$shlibpath_var if the +# "absolute",i.e. impossible to change by setting \$shlibpath_var if the # library is relocated. hardcode_direct_absolute=$hardcode_direct_absolute @@ -27399,7 +28582,7 @@ ltmain=$ac_aux_dir/ltmain.sh # if finds mixed CR/LF and LF-only lines. Since sed operates in # text mode, it properly converts lines to CR/LF. This bash problem # is reportedly fixed, but why not run on old versions too? - sed '$q' "$ltmain" >> "$cfgfile" \ + $SED '$q' "$ltmain" >> "$cfgfile" \ || (rm -f "$cfgfile"; exit 1) mv -f "$cfgfile" "$ofile" || Index: usr.sbin/unbound/configure.ac =================================================================== RCS file: /cvs/src/usr.sbin/unbound/configure.ac,v diff -u -p -r1.59 configure.ac --- usr.sbin/unbound/configure.ac 26 Sep 2025 07:32:36 -0000 1.59 +++ usr.sbin/unbound/configure.ac 21 Sep 2026 16:28:31 -0000 @@ -11,15 +11,15 @@ sinclude(dnscrypt/dnscrypt.m4) # must be numbers. ac_defun because of later processing m4_define([VERSION_MAJOR],[1]) -m4_define([VERSION_MINOR],[24]) -m4_define([VERSION_MICRO],[0]) +m4_define([VERSION_MINOR],[26]) +m4_define([VERSION_MICRO],[1]) 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]) AC_SUBST(UNBOUND_VERSION_MINOR, [VERSION_MINOR]) AC_SUBST(UNBOUND_VERSION_MICRO, [VERSION_MICRO]) LIBUNBOUND_CURRENT=9 -LIBUNBOUND_REVISION=33 +LIBUNBOUND_REVISION=40 LIBUNBOUND_AGE=1 # 1.0.0 had 0:12:0 # 1.0.1 had 0:13:0 @@ -120,6 +120,13 @@ LIBUNBOUND_AGE=1 # 1.23.0 had 9:31:1 # 1.23.1 had 9:32:1 # 1.24.0 had 9:33:1 +# 1.24.1 had 9:34:1 +# 1.24.2 had 9:35:1 +# 1.25.0 had 9:36:1 +# 1.25.1 had 9:37:1 +# 1.25.2 had 9:38:1 +# 1.26.0 had 9:39:1 +# 1.26.1 had 9:40:1 # Current -- the number of the binary API that we're implementing # Revision -- which iteration of the implementation of the binary @@ -328,6 +335,7 @@ fi AC_C_INLINE ACX_CHECK_FORMAT_ATTRIBUTE ACX_CHECK_UNUSED_ATTRIBUTE +ACX_CHECK_NONSTRING_ATTRIBUTE AC_DEFUN([CHECK_WEAK_ATTRIBUTE], [AC_REQUIRE([AC_PROG_CC]) @@ -358,7 +366,14 @@ AC_MSG_CHECKING(whether the C compiler ( AC_CACHE_VAL(ac_cv_c_noreturn_attribute, [ac_cv_c_noreturn_attribute=no AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[ #include -__attribute__((noreturn)) void f(int x) { printf("%d", x); } +#ifdef STDC_HEADERS +# include +#else +# ifdef HAVE_STDLIB_H +# include +# endif +#endif +__attribute__((noreturn)) void f(int x) { printf("%d", x); exit(1); } ]], [[ f(1); ]])],[ac_cv_c_noreturn_attribute="yes"],[ac_cv_c_noreturn_attribute="no"]) @@ -470,7 +485,7 @@ PKG_PROG_PKG_CONFIG fi # Checks for header files. -AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h poll.h],,, [AC_INCLUDES_DEFAULT]) +AC_CHECK_HEADERS([stdarg.h stdbool.h netinet/in.h netinet/tcp.h sys/param.h sys/select.h sys/socket.h sys/un.h sys/uio.h sys/resource.h arpa/inet.h syslog.h netdb.h sys/wait.h pwd.h glob.h fnmatch.h grp.h login_cap.h winsock2.h ws2tcpip.h endian.h sys/endian.h libkern/OSByteOrder.h sys/ipc.h sys/shm.h ifaddrs.h poll.h],,, [AC_INCLUDES_DEFAULT]) # net/if.h portability for Darwin see: # https://www.gnu.org/software/autoconf/manual/autoconf-2.69/html_node/Header-Portability.html AC_CHECK_HEADERS([net/if.h],,, [ @@ -633,19 +648,19 @@ AC_ARG_ENABLE(alloc-nonregional, AS_HELP if test x_$enable_alloc_nonregional = x_yes; then AC_DEFINE(UNBOUND_ALLOC_NONREGIONAL, 1, [use malloc not regions, for debug use]) fi -if test x_$enable_alloc_checks = x_yes; then +AS_IF([test x_$enable_alloc_checks = x_yes],[ AC_DEFINE(UNBOUND_ALLOC_STATS, 1, [use statistics for allocs and frees, for debug use]) SLDNS_ALLOCCHECK_EXTRA_OBJ="alloc.lo log.lo" AC_SUBST(SLDNS_ALLOCCHECK_EXTRA_OBJ) ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ="alloc.lo" AC_SUBST(ASYNCLOOK_ALLOCCHECK_EXTRA_OBJ) -else - if test x_$enable_alloc_lite = x_yes; then +],[ + AS_IF([test x_$enable_alloc_lite = x_yes],[ AC_DEFINE(UNBOUND_ALLOC_LITE, 1, [use to enable lightweight alloc assertions, for debug use]) - else + ],[ ACX_FUNC_MALLOC([unbound]) - fi -fi + ]) +]) # check windows threads (we use them, not pthreads, on windows). if test "$on_mingw" = "yes"; then @@ -720,6 +735,76 @@ int main(void) {return 0;} ]) fi +if test x_$ub_have_pthreads != x_no; then + # Long checks to support pthread_setname_np(). + # Some OSes have the extra non-portable functions in a specific + # header file. + AC_CHECK_HEADERS([pthread_np.h],,, [AC_INCLUDES_DEFAULT]) + BAKCFLAGS="$CFLAGS" + CFLAGS="$CFLAGS -Werror" + # MacOS only has 1 argument, the name. + AC_MSG_CHECKING([whether pthread_setname_np has only 1 argument]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT +#include +#ifdef HAVE_PTHREAD_NP_H +#include +#endif + ],[ + (void)pthread_setname_np(""); + ])],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PTHREAD_SETNAME_NP1, 1, [Define if pthread_setname_np has only 1 argument.]) + ],[ + AC_MSG_RESULT(no) + ]) + # NetBSD has 3 arguments to allow for formatting of the name. + AC_MSG_CHECKING([whether pthread_setname_np has 3 arguments]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT +#include +#ifdef HAVE_PTHREAD_NP_H +#include +#endif + ],[ + (void)pthread_setname_np(0, "", NULL); + ])],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PTHREAD_SETNAME_NP3, 1, [Define if pthread_setname_np has 3 arguments.]) + ],[ + AC_MSG_RESULT(no) + ]) + # Most OSes have the common 2 arguments, thread and name. + AC_MSG_CHECKING([whether pthread_setname_np has the common 2 arguments]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT +#include +#ifdef HAVE_PTHREAD_NP_H +#include +#endif + ],[ + (void)pthread_setname_np(0, ""); + ])],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PTHREAD_SETNAME_NP, 1, [Define if pthread_setname_np has the common 2 arguments.]) + ],[ + AC_MSG_RESULT(no) + ]) + # FreeBSD/OpenBSD use a slightly different function name. + AC_MSG_CHECKING([whether pthread_setname_np exists as pthread_set_name_np instead]) + AC_COMPILE_IFELSE([AC_LANG_PROGRAM([AC_INCLUDES_DEFAULT +#include +#ifdef HAVE_PTHREAD_NP_H +#include +#endif + ],[ + (void)pthread_set_name_np(0, ""); + ])],[ + AC_MSG_RESULT(yes) + AC_DEFINE(HAVE_PTHREAD_SET_NAME_NP, 1, [Define if pthread_setname_np exists as pthread_set_name_np instead.]) + ],[ + AC_MSG_RESULT(no) + ]) + CFLAGS="$BAKCFLAGS" +fi + # check solaris thread library AC_ARG_WITH(solaris-threads, AS_HELP_STRING([--with-solaris-threads],[use solaris native thread library.]), [ ],[ withval="no" ]) ub_have_sol_threads=no @@ -997,12 +1082,19 @@ else AC_MSG_RESULT([no]) fi AC_CHECK_HEADERS([openssl/conf.h openssl/engine.h openssl/bn.h openssl/dh.h openssl/dsa.h openssl/rsa.h openssl/core_names.h openssl/param_build.h],,, [AC_INCLUDES_DEFAULT]) -AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_default_properties_is_fips_enabled EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params OSSL_PARAM_BLD_new BIO_set_callback_ex]) +AC_CHECK_FUNCS([OPENSSL_config EVP_sha1 EVP_sha256 EVP_sha512 FIPS_mode EVP_default_properties_is_fips_enabled EVP_MD_CTX_new OpenSSL_add_all_digests OPENSSL_init_crypto EVP_cleanup ENGINE_cleanup ERR_load_crypto_strings CRYPTO_cleanup_all_ex_data ERR_free_strings RAND_cleanup DSA_SIG_set0 EVP_dss1 EVP_DigestVerify EVP_aes_256_cbc EVP_EncryptInit_ex HMAC_Init_ex CRYPTO_THREADID_set_callback EVP_MAC_CTX_set_params OSSL_PARAM_BLD_new BIO_set_callback_ex OPENSSL_cleanup]) # these check_funcs need -lssl BAKLIBS="$LIBS" LIBS="-lssl $LIBS" -AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb SSL_CTX_set_alpn_select_cb SSL_get0_alpn_selected SSL_CTX_set_alpn_protos SSL_get1_peer_certificate]) +AC_CHECK_FUNCS([OPENSSL_init_ssl SSL_CTX_set_security_level SSL_set1_host SSL_get0_peername SSL_set1_dnsname X509_get_key_usage ASN1_STRING_get0_data X509_VERIFY_PARAM_set1_host SSL_CTX_set_ciphersuites SSL_CTX_set_tlsext_ticket_key_evp_cb SSL_CTX_set_alpn_select_cb SSL_get0_alpn_selected SSL_CTX_set_alpn_protos SSL_get1_peer_certificate]) +AC_CHECK_FUNCS([X509_NAME_get_text_by_NID]) +if test $ac_cv_func_X509_NAME_get_text_by_NID = yes; then + ACX_FUNC_DEPRECATED([X509_NAME_get_text_by_NID], [ + (void)X509_NAME_get_text_by_NID(NULL, 0, NULL, 0);], [ +#include "openssl/x509.h" +]) +fi LIBS="$BAKLIBS" AC_CHECK_DECLS([SSL_COMP_get_compression_methods,sk_SSL_COMP_pop_free,SSL_CTX_set_ecdh_auto,SSL_CTX_set_tmp_ecdh], [], [], [ @@ -1251,7 +1343,7 @@ case "$enable_ecdsa" in # see if OPENSSL 1.0.0 or later (has EVP MD and Verify independency) AC_MSG_CHECKING([if openssl supports SHA2 and ECDSA with EVP]) if grep OPENSSL_VERSION_TEXT $ssldir_include/openssl/opensslv.h | grep "OpenSSL" >/dev/null; then - if grep OPENSSL_VERSION_NUMBER $ssldir_include/openssl/opensslv.h | grep 0x0 >/dev/null; then + if grep OPENSSL_VERSION_TEXT $ssldir_include/openssl/opensslv.h | grep "OpenSSL 0\." >/dev/null; then AC_MSG_RESULT([no]) AC_DEFINE_UNQUOTED([USE_ECDSA_EVP_WORKAROUND], [1], [Define this to enable an EVP workaround for older openssl]) else @@ -1621,6 +1713,9 @@ if test x_$withval = x_yes -o x_$withval AC_CHECK_LIB([ngtcp2_crypto_ossl], [ngtcp2_crypto_encrypt_cb], [ LIBS="$LIBS -lngtcp2_crypto_ossl" AC_DEFINE(USE_NGTCP2_CRYPTO_OSSL, 1, [Define this to use ngtcp2_crypto_ossl.]) + AC_CHECK_DECLS([ngtcp2_crypto_ossl_ctx_new], [], [AC_MSG_ERROR([No declaration of ngtcp2_crypto_ossl_ctx_new in the ngtcp2_crypto_ossl header file. Perhaps the ngtcp2_crypto_ossl devel header files need to be installed.])], [AC_INCLUDES_DEFAULT + #include + ]) ], [ AC_CHECK_LIB([ngtcp2_crypto_openssl], [ngtcp2_crypto_encrypt_cb], [ LIBS="$LIBS -lngtcp2_crypto_openssl" ], [ AC_CHECK_LIB([ngtcp2_crypto_quictls], [ngtcp2_crypto_encrypt_cb], [ LIBS="$LIBS -lngtcp2_crypto_quictls" ]) @@ -1632,6 +1727,7 @@ if test x_$withval = x_yes -o x_$withval BAKLIBS="$LIBS" LIBS="-lssl $LIBS" AC_CHECK_FUNCS([SSL_is_quic], [], [AC_MSG_ERROR([No QUIC support detected in OpenSSL. Need OpenSSL version with QUIC support to enable DNS over QUIC with libngtcp2.])]) + AC_CHECK_FUNCS([SSL_set_quic_tls_early_data_enabled]) LIBS="$BAKLIBS" AC_CHECK_TYPES([struct ngtcp2_version_cid, ngtcp2_encryption_level],,,[AC_INCLUDES_DEFAULT @@ -1653,6 +1749,22 @@ if test x_$withval = x_yes -o x_$withval AC_MSG_RESULT(no) ]) + AC_CHECK_DECL([CLOCK_MONOTONIC] + , [] + , [AC_MSG_ERROR([ngtcp2 for QUIC needs at least CLOCK_MONOTONIC on the system])] + , [AC_INCLUDES_DEFAULT +#ifdef TIME_WITH_SYS_TIME +# include +# include +#else +# ifdef HAVE_SYS_TIME_H +# include +# else +# include +# endif +#endif + ]) + fi # set static linking for uninstalled libraries if requested @@ -1671,10 +1783,12 @@ if test x_$enable_static_exe = x_yes; th LIBS="$LIBS -lgdi32" fi AC_CHECK_LIB([z], [compress], [ LIBS="$LIBS -lz" ]) - if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then - : - else - LIBS="$LIBS -l:libssp.a" + if echo "$host" | $GREP -i -e linux >/dev/null; then + if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then + : + else + LIBS="$LIBS -l:libssp.a" + fi fi fi fi @@ -1692,10 +1806,12 @@ if test x_$enable_fully_static = x_yes; LIBS="$LIBS -lgdi32" fi AC_CHECK_LIB([z], [compress], [ LIBS="$LIBS -lz" ]) - if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then - : - else - LIBS="$LIBS -l:libssp.a" + if echo "$host" | $GREP -i -e linux >/dev/null; then + if echo "$LIBS" | grep -e "libssp.a" -e "lssp" >/dev/null; then + : + else + LIBS="$LIBS -l:libssp.a" + fi fi fi fi @@ -1754,6 +1870,7 @@ if test $ac_cv_func_daemon = yes; then ]) fi +AC_CHECK_MEMBERS([struct stat.st_mtimensec, struct stat.st_mtim.tv_nsec]) AC_CHECK_MEMBERS([struct sockaddr_un.sun_len],,,[ AC_INCLUDES_DEFAULT #ifdef HAVE_SYS_UN_H @@ -1824,7 +1941,7 @@ AC_LINK_IFELSE([AC_LANG_PROGRAM([ AC_MSG_RESULT(no)) AC_SEARCH_LIBS([setusercontext], [util]) -AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4 getifaddrs if_nametoindex poll gettid]) +AC_CHECK_FUNCS([tzset sigprocmask fcntl getpwnam endpwent getrlimit setrlimit setsid chroot kill chown sleep usleep random srandom recvmsg sendmsg writev socketpair glob fnmatch initgroups strftime localtime_r setusercontext _beginthreadex endservent endprotoent fsync shmget accept4 getifaddrs if_nametoindex poll gettid]) AC_CHECK_FUNCS([setresuid],,[AC_CHECK_FUNCS([setreuid])]) AC_CHECK_FUNCS([setresgid],,[AC_CHECK_FUNCS([setregid])]) @@ -2291,6 +2408,7 @@ dnl includes AHX_CONFIG_FORMAT_ATTRIBUTE AHX_CONFIG_UNUSED_ATTRIBUTE +AHX_CONFIG_NONSTRING_ATTRIBUTE AHX_CONFIG_FSEEKO AHX_CONFIG_MAXHOSTNAMELEN #if !defined(HAVE_SNPRINTF) || defined(SNPRINTF_RET_BROKEN) Index: usr.sbin/unbound/install-sh =================================================================== RCS file: /cvs/src/usr.sbin/unbound/install-sh,v diff -u -p -r1.7 install-sh --- usr.sbin/unbound/install-sh 21 Feb 2025 13:20:39 -0000 1.7 +++ usr.sbin/unbound/install-sh 21 Sep 2026 16:28:31 -0000 @@ -1,7 +1,7 @@ #!/usr/bin/sh # install - install a program, script, or datafile -scriptversion=2013-12-25.23; # UTC +scriptversion=2024-06-19.01; # UTC # This originates from X11R5 (mit/util/scripts/install.sh), which was # later released in X11R6 (xc/config/util/install.sh) with the @@ -69,6 +69,11 @@ posix_mkdir= # Desired mode of installed file. mode=0755 +# Create dirs (including intermediate dirs) using mode 755. +# This is like GNU 'install' as of coreutils 8.32 (2020). +mkdir_umask=22 + +backupsuffix= chgrpcmd= chmodcmd=$chmodprog chowncmd= @@ -99,19 +104,29 @@ Options: --version display version info and exit. -c (ignored) - -C install only if different (preserve the last data modification time) + -C install only if different (preserve data modification time) -d create directories instead of installing files. -g GROUP $chgrpprog installed files to GROUP. -m MODE $chmodprog installed files to MODE. -o USER $chownprog installed files to USER. + -p pass -p to $cpprog. -s $stripprog installed files. + -S SUFFIX attempt to back up existing files, with suffix SUFFIX. -t DIRECTORY install into DIRECTORY. -T report an error if DSTFILE is a directory. Environment variables override the default commands: CHGRPPROG CHMODPROG CHOWNPROG CMPPROG CPPROG MKDIRPROG MVPROG RMPROG STRIPPROG -" + +By default, rm is invoked with -f; when overridden with RMPROG, +it's up to you to specify -f if you want it. + +If -S is not specified, no backups are attempted. + +Report bugs to . +GNU Automake home page: . +General help using GNU software: ." while test $# -ne 0; do case $1 in @@ -137,8 +152,13 @@ while test $# -ne 0; do -o) chowncmd="$chownprog $2" shift;; + -p) cpprog="$cpprog -p";; + -s) stripcmd=$stripprog;; + -S) backupsuffix="$2" + shift;; + -t) is_target_a_directory=always dst_arg=$2 @@ -150,7 +170,7 @@ while test $# -ne 0; do -T) is_target_a_directory=never;; - --version) echo "$0 $scriptversion"; exit $?;; + --version) echo "$0 (GNU Automake) $scriptversion"; exit $?;; --) shift break;; @@ -255,6 +275,10 @@ do dstdir=$dst test -d "$dstdir" dstdir_status=$? + # Don't chown directories that already exist. + if test $dstdir_status = 0; then + chowncmd="" + fi else # Waiting for this to be detected by the "$cpprog $src $dsttmp" command @@ -271,15 +295,18 @@ do fi dst=$dst_arg - # If destination is a directory, append the input filename; won't work - # if double slashes aren't ignored. + # If destination is a directory, append the input filename. if test -d "$dst"; then if test "$is_target_a_directory" = never; then echo "$0: $dst_arg: Is a directory" >&2 exit 1 fi dstdir=$dst - dst=$dstdir/`basename "$src"` + dstbase=`basename "$src"` + case $dst in + */) dst=$dst$dstbase;; + *) dst=$dst/$dstbase;; + esac dstdir_status=0 else dstdir=`dirname "$dst"` @@ -288,27 +315,16 @@ do fi fi + case $dstdir in + */) dstdirslash=$dstdir;; + *) dstdirslash=$dstdir/;; + esac + obsolete_mkdir_used=false if test $dstdir_status != 0; then case $posix_mkdir in '') - # Create intermediate dirs using mode 755 as modified by the umask. - # This is like FreeBSD 'install' as of 1997-10-28. - umask=`umask` - case $stripcmd.$umask in - # Optimize common cases. - *[2367][2367]) mkdir_umask=$umask;; - .*0[02][02] | .[02][02] | .[02]) mkdir_umask=22;; - - *[0-7]) - mkdir_umask=`expr $umask + 22 \ - - $umask % 100 % 40 + $umask % 20 \ - - $umask % 10 % 4 + $umask % 2 - `;; - *) mkdir_umask=$umask,go-w;; - esac - # With -d, create the new directory with the user-specified mode. # Otherwise, rely on $mkdir_umask. if test -n "$dir_arg"; then @@ -318,43 +334,49 @@ do fi posix_mkdir=false - case $umask in - *[123567][0-7][0-7]) - # POSIX mkdir -p sets u+wx bits regardless of umask, which - # is incompatible with FreeBSD 'install' when (umask & 300) != 0. - ;; - *) - tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ - trap 'ret=$?; rmdir "$tmpdir/d" "$tmpdir" 2>/dev/null; exit $ret' 0 - - if (umask $mkdir_umask && - exec $mkdirprog $mkdir_mode -p -- "$tmpdir/d") >/dev/null 2>&1 - then - if test -z "$dir_arg" || { - # Check for POSIX incompatibilities with -m. - # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or - # other-writable bit of parent directory when it shouldn't. - # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. - ls_ld_tmpdir=`ls -ld "$tmpdir"` - case $ls_ld_tmpdir in - d????-?r-*) different_mode=700;; - d????-?--*) different_mode=755;; - *) false;; - esac && - $mkdirprog -m$different_mode -p -- "$tmpdir" && { - ls_ld_tmpdir_1=`ls -ld "$tmpdir"` - test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" - } - } - then posix_mkdir=: - fi - rmdir "$tmpdir/d" "$tmpdir" - else - # Remove any dirs left behind by ancient mkdir implementations. - rmdir ./$mkdir_mode ./-p ./-- 2>/dev/null - fi - trap '' 0;; - esac;; + # The $RANDOM variable is not portable (e.g., dash). Use it + # here however when possible just to lower collision chance. + tmpdir=${TMPDIR-/tmp}/ins$RANDOM-$$ + + trap ' + ret=$? + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" 2>/dev/null + exit $ret + ' 0 + + # Because "mkdir -p" follows existing symlinks and we likely work + # directly in world-writable /tmp, make sure that the '$tmpdir' + # directory is successfully created first before we actually test + # 'mkdir -p'. + if (umask $mkdir_umask && + $mkdirprog $mkdir_mode "$tmpdir" && + exec $mkdirprog $mkdir_mode -p -- "$tmpdir/a/b") >/dev/null 2>&1 + then + if test -z "$dir_arg" || { + # Check for POSIX incompatibility with -m. + # HP-UX 11.23 and IRIX 6.5 mkdir -m -p sets group- or + # other-writable bit of parent directory when it shouldn't. + # FreeBSD 6.1 mkdir -m -p sets mode of existing directory. + test_tmpdir="$tmpdir/a" + ls_ld_tmpdir=`ls -ld "$test_tmpdir"` + case $ls_ld_tmpdir in + d????-?r-*) different_mode=700;; + d????-?--*) different_mode=755;; + *) false;; + esac && + $mkdirprog -m$different_mode -p -- "$test_tmpdir" && { + ls_ld_tmpdir_1=`ls -ld "$test_tmpdir"` + test "$ls_ld_tmpdir" = "$ls_ld_tmpdir_1" + } + } + then posix_mkdir=: + fi + rmdir "$tmpdir/a/b" "$tmpdir/a" "$tmpdir" + else + # Remove any dirs left behind by ancient mkdir implementations. + rmdir ./$mkdir_mode ./-p ./-- "$tmpdir" 2>/dev/null + fi + trap '' 0;; esac if @@ -365,7 +387,7 @@ do then : else - # The umask is ridiculous, or mkdir does not conform to POSIX, + # mkdir does not conform to POSIX, # or it failed possibly due to a race condition. Create the # directory the slow way, step by step, checking for races as we go. @@ -394,7 +416,7 @@ do prefixes= else if $posix_mkdir; then - (umask=$mkdir_umask && + (umask $mkdir_umask && $doit_exec $mkdirprog $mkdir_mode -p -- "$dstdir") && break # Don't fail if two instances are running concurrently. test -d "$prefix" || exit 1 @@ -427,14 +449,25 @@ do else # Make a couple of temp file names in the proper directory. - dsttmp=$dstdir/_inst.$$_ - rmtmp=$dstdir/_rm.$$_ + dsttmp=${dstdirslash}_inst.$$_ + rmtmp=${dstdirslash}_rm.$$_ # Trap to clean up those temp files at exit. trap 'ret=$?; rm -f "$dsttmp" "$rmtmp" && exit $ret' 0 # Copy the file name to the temp name. - (umask $cp_umask && $doit_exec $cpprog "$src" "$dsttmp") && + (umask $cp_umask && + { test -z "$stripcmd" || { + # Create $dsttmp read-write so that cp doesn't create it read-only, + # which would cause strip to fail. + if test -z "$doit"; then + : >"$dsttmp" # No need to fork-exec 'touch'. + else + $doit touch "$dsttmp" + fi + } + } && + $doit_exec $cpprog "$src" "$dsttmp") && # and set any options; do chmod last to preserve setuid bits. # @@ -460,6 +493,13 @@ do then rm -f "$dsttmp" else + # If $backupsuffix is set, and the file being installed + # already exists, attempt a backup. Don't worry if it fails, + # e.g., if mv doesn't support -f. + if test -n "$backupsuffix" && test -f "$dst"; then + $doit $mvcmd -f "$dst" "$dst$backupsuffix" 2>/dev/null + fi + # Rename the file to the real destination. $doit $mvcmd -f "$dsttmp" "$dst" 2>/dev/null || @@ -474,9 +514,9 @@ do # file should still install successfully. { test ! -f "$dst" || - $doit $rmcmd -f "$dst" 2>/dev/null || + $doit $rmcmd "$dst" 2>/dev/null || { $doit $mvcmd -f "$dst" "$rmtmp" 2>/dev/null && - { $doit $rmcmd -f "$rmtmp" 2>/dev/null; :; } + { $doit $rmcmd "$rmtmp" 2>/dev/null; :; } } || { echo "$0: cannot unlink or rename $dst" >&2 (exit 1); exit 1 @@ -493,9 +533,9 @@ do done # Local variables: -# eval: (add-hook 'write-file-hooks 'time-stamp) +# eval: (add-hook 'before-save-hook 'time-stamp) # time-stamp-start: "scriptversion=" # time-stamp-format: "%:y-%02m-%02d.%02H" -# time-stamp-time-zone: "UTC" +# time-stamp-time-zone: "UTC0" # time-stamp-end: "; # UTC" # End: Index: usr.sbin/unbound/ltmain.sh =================================================================== RCS file: /cvs/src/usr.sbin/unbound/ltmain.sh,v diff -u -p -r1.6 ltmain.sh --- usr.sbin/unbound/ltmain.sh 21 Feb 2025 13:20:39 -0000 1.6 +++ usr.sbin/unbound/ltmain.sh 21 Sep 2026 16:28:31 -0000 @@ -1,12 +1,12 @@ -#! /bin/sh +#! /usr/bin/env sh ## DO NOT EDIT - This file generated from ./build-aux/ltmain.in -## by inline-source v2014-01-03.01 +## by inline-source v2019-02-19.15 -# libtool (GNU libtool) 2.4.6 +# libtool (GNU libtool) 2.5.4 # Provide generalized library-building support services. # Written by Gordon Matzigkeit , 1996 -# Copyright (C) 1996-2015 Free Software Foundation, Inc. +# Copyright (C) 1996-2019, 2021-2024 Free Software Foundation, Inc. # This is free software; see the source for copying conditions. There is NO # warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. @@ -31,8 +31,8 @@ PROGRAM=libtool PACKAGE=libtool -VERSION=2.4.6 -package_revision=2.4.6 +VERSION=2.5.4 +package_revision=2.5.4 ## ------ ## @@ -64,34 +64,25 @@ package_revision=2.4.6 # libraries, which are installed to $pkgauxdir. # Set a version string for this script. -scriptversion=2015-01-20.17; # UTC +scriptversion=2019-02-19.15; # UTC # General shell script boiler plate, and helper functions. # Written by Gary V. Vaughan, 2004 -# Copyright (C) 2004-2015 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# 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. - -# As a special exception to the GNU General Public License, if you distribute -# this file as part of a program or library that is built using GNU Libtool, -# you may include this file under the same distribution terms that you use -# for the rest of that program. - -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNES 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 . +# This is free software. There is NO warranty; not even for +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Copyright (C) 2004-2019, 2021, 2023-2024 Bootstrap Authors +# +# This file is dual licensed under the terms of the MIT license +# , and GPL version 2 or later +# . You must apply one of +# these licenses when using or redistributing this software or any of +# the files within it. See the URLs above, or the file `LICENSE` +# included in the Bootstrap distribution for the full license texts. -# Please report bugs or propose patches to gary@gnu.org. +# Please report bugs or propose patches to: +# ## ------ ## @@ -139,9 +130,12 @@ do _G_safe_locale=\"$_G_var=C; \$_G_safe_locale\" fi" done - -# CDPATH. -(unset CDPATH) >/dev/null 2>&1 && unset CDPATH +# These NLS vars are set unconditionally (bootstrap issue #24). Unset those +# in case the environment reset is needed later and the $save_* variant is not +# defined (see the code above). +LC_ALL=C +LANGUAGE=C +export LANGUAGE LC_ALL # Make sure IFS has a sensible default sp=' ' @@ -149,7 +143,7 @@ nl=' ' IFS="$sp $nl" -# There are apparently some retarded systems that use ';' as a PATH separator! +# There are apparently some systems that use ';' as a PATH separator! if test "${PATH_SEPARATOR+set}" != set; then PATH_SEPARATOR=: (PATH='/bin;/bin'; FPATH=$PATH; sh -c :) >/dev/null 2>&1 && { @@ -159,6 +153,26 @@ if test "${PATH_SEPARATOR+set}" != set; fi +# func_unset VAR +# -------------- +# Portably unset VAR. +# In some shells, an 'unset VAR' statement leaves a non-zero return +# status if VAR is already unset, which might be problematic if the +# statement is used at the end of a function (thus poisoning its return +# value) or when 'set -e' is active (causing even a spurious abort of +# the script in this case). +func_unset () +{ + { eval $1=; (eval unset $1) >/dev/null 2>&1 && eval unset $1 || : ; } +} + + +# Make sure CDPATH doesn't cause `cd` commands to output the target dir. +func_unset CDPATH + +# Make sure ${,E,F}GREP behave sanely. +func_unset GREP_OPTIONS + ## ------------------------- ## ## Locate command utilities. ## @@ -259,7 +273,7 @@ test -z "$SED" && { rm -f conftest.in conftest.tmp conftest.nl conftest.out } - func_path_progs "sed gsed" func_check_prog_sed $PATH:/usr/xpg4/bin + func_path_progs "sed gsed" func_check_prog_sed "$PATH:/usr/xpg4/bin" rm -f conftest.sed SED=$func_path_progs_result } @@ -295,7 +309,7 @@ test -z "$GREP" && { rm -f conftest.in conftest.tmp conftest.nl conftest.out } - func_path_progs "grep ggrep" func_check_prog_grep $PATH:/usr/xpg4/bin + func_path_progs "grep ggrep" func_check_prog_grep "$PATH:/usr/xpg4/bin" GREP=$func_path_progs_result } @@ -360,6 +374,35 @@ sed_double_backslash="\ s/\\([^$_G_bs]\\)$_G_bs2$_G_dollar/\\1$_G_bs2$_G_bs$_G_dollar/g s/\n//g" +# require_check_ifs_backslash +# --------------------------- +# Check if we can use backslash as IFS='\' separator, and set +# $check_ifs_backshlash_broken to ':' or 'false'. +require_check_ifs_backslash=func_require_check_ifs_backslash +func_require_check_ifs_backslash () +{ + _G_save_IFS=$IFS + IFS='\' + _G_check_ifs_backshlash='a\\b' + for _G_i in $_G_check_ifs_backshlash + do + case $_G_i in + a) + check_ifs_backshlash_broken=false + ;; + '') + break + ;; + *) + check_ifs_backshlash_broken=: + break + ;; + esac + done + IFS=$_G_save_IFS + require_check_ifs_backslash=: +} + ## ----------------- ## ## Global variables. ## @@ -546,7 +589,7 @@ func_require_term_colors () # _G_HAVE_PLUSEQ_OP # Can be empty, in which case the shell is probed, "yes" if += is - # useable or anything else if it does not work. + # usable or anything else if it does not work. test -z "$_G_HAVE_PLUSEQ_OP" \ && (eval 'x=a; x+=" b"; test "a b" = "$x"') 2>/dev/null \ && _G_HAVE_PLUSEQ_OP=yes @@ -580,16 +623,16 @@ if test yes = "$_G_HAVE_PLUSEQ_OP"; then { $debug_cmd - func_quote_for_eval "$2" - eval "$1+=\\ \$func_quote_for_eval_result" + func_quote_arg pretty "$2" + eval "$1+=\\ \$func_quote_arg_result" }' else func_append_quoted () { $debug_cmd - func_quote_for_eval "$2" - eval "$1=\$$1\\ \$func_quote_for_eval_result" + func_quote_arg pretty "$2" + eval "$1=\$$1\\ \$func_quote_arg_result" } fi @@ -696,7 +739,7 @@ eval 'func_dirname () # to NONDIR_REPLACEMENT. # value returned in "$func_dirname_result" # basename: Compute filename of FILE. -# value retuned in "$func_basename_result" +# value returned in "$func_basename_result" # For efficiency, we do not delegate to the functions above but instead # duplicate the functionality here. eval 'func_dirname_and_basename () @@ -854,7 +897,7 @@ func_mkdir_p () # While some portion of DIR does not yet exist... while test ! -d "$_G_directory_path"; do # ...make a list in topmost first order. Use a colon delimited - # list incase some portion of path contains whitespace. + # list in case some portion of path contains whitespace. _G_dir_list=$_G_directory_path:$_G_dir_list # If the last portion added has no slash in it, the list is done @@ -1091,85 +1134,203 @@ func_relative_path () } -# func_quote_for_eval ARG... -# -------------------------- -# Aesthetically quote ARGs to be evaled later. -# This function returns two values: -# i) func_quote_for_eval_result -# double-quoted, suitable for a subsequent eval -# ii) func_quote_for_eval_unquoted_result -# has all characters that are still active within double -# quotes backslashified. -func_quote_for_eval () +# func_quote_portable EVAL ARG +# ---------------------------- +# Internal function to portably implement func_quote_arg. Note that we still +# keep attention to performance here so we as much as possible try to avoid +# calling sed binary (so far O(N) complexity as long as func_append is O(1)). +func_quote_portable () { $debug_cmd - func_quote_for_eval_unquoted_result= - func_quote_for_eval_result= - while test 0 -lt $#; do - case $1 in - *[\\\`\"\$]*) - _G_unquoted_arg=`printf '%s\n' "$1" |$SED "$sed_quote_subst"` ;; - *) - _G_unquoted_arg=$1 ;; - esac - if test -n "$func_quote_for_eval_unquoted_result"; then - func_append func_quote_for_eval_unquoted_result " $_G_unquoted_arg" - else - func_append func_quote_for_eval_unquoted_result "$_G_unquoted_arg" + $require_check_ifs_backslash + + func_quote_portable_result=$2 + + # one-time-loop (easy break) + while true + do + if $1; then + func_quote_portable_result=`$ECHO "$2" | $SED \ + -e "$sed_double_quote_subst" -e "$sed_double_backslash"` + break fi - case $_G_unquoted_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting, command substitution and variable expansion - # for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - _G_quoted_arg=\"$_G_unquoted_arg\" + # Quote for eval. + case $func_quote_portable_result in + *[\\\`\"\$]*) + # Fallback to sed for $func_check_bs_ifs_broken=:, or when the string + # contains the shell wildcard characters. + case $check_ifs_backshlash_broken$func_quote_portable_result in + :*|*[\[\*\?]*) + func_quote_portable_result=`$ECHO "$func_quote_portable_result" \ + | $SED "$sed_quote_subst"` + break + ;; + esac + + func_quote_portable_old_IFS=$IFS + for _G_char in '\' '`' '"' '$' + do + # STATE($1) PREV($2) SEPARATOR($3) + set start "" "" + func_quote_portable_result=dummy"$_G_char$func_quote_portable_result$_G_char"dummy + IFS=$_G_char + for _G_part in $func_quote_portable_result + do + case $1 in + quote) + func_append func_quote_portable_result "$3$2" + set quote "$_G_part" "\\$_G_char" + ;; + start) + set first "" "" + func_quote_portable_result= + ;; + first) + set quote "$_G_part" "" + ;; + esac + done + done + IFS=$func_quote_portable_old_IFS ;; - *) - _G_quoted_arg=$_G_unquoted_arg - ;; + *) ;; esac - - if test -n "$func_quote_for_eval_result"; then - func_append func_quote_for_eval_result " $_G_quoted_arg" - else - func_append func_quote_for_eval_result "$_G_quoted_arg" - fi - shift + break done + + func_quote_portable_unquoted_result=$func_quote_portable_result + case $func_quote_portable_result in + # double-quote args containing shell metacharacters to delay + # word splitting, command substitution and variable expansion + # for a subsequent eval. + # many bourne shells cannot handle close brackets correctly + # in scan sets, so we specify it separately. + *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") + func_quote_portable_result=\"$func_quote_portable_result\" + ;; + esac } -# func_quote_for_expand ARG -# ------------------------- -# Aesthetically quote ARG to be evaled later; same as above, -# but do not quote variable references. -func_quote_for_expand () -{ - $debug_cmd +# func_quotefast_eval ARG +# ----------------------- +# Quote one ARG (internal). This is equivalent to 'func_quote_arg eval ARG', +# but optimized for speed. Result is stored in $func_quotefast_eval. +if test xyes = `(x=; printf -v x %q yes; echo x"$x") 2>/dev/null`; then + printf -v _GL_test_printf_tilde %q '~' + if test '\~' = "$_GL_test_printf_tilde"; then + func_quotefast_eval () + { + printf -v func_quotefast_eval_result %q "$1" + } + else + # Broken older Bash implementations. Make those faster too if possible. + func_quotefast_eval () + { + case $1 in + '~'*) + func_quote_portable false "$1" + func_quotefast_eval_result=$func_quote_portable_result + ;; + *) + printf -v func_quotefast_eval_result %q "$1" + ;; + esac + } + fi +else + func_quotefast_eval () + { + func_quote_portable false "$1" + func_quotefast_eval_result=$func_quote_portable_result + } +fi - case $1 in - *[\\\`\"]*) - _G_arg=`$ECHO "$1" | $SED \ - -e "$sed_double_quote_subst" -e "$sed_double_backslash"` ;; - *) - _G_arg=$1 ;; + +# func_quote_arg MODEs ARG +# ------------------------ +# Quote one ARG to be evaled later. MODEs argument may contain zero or more +# specifiers listed below separated by ',' character. This function returns two +# values: +# i) func_quote_arg_result +# double-quoted (when needed), suitable for a subsequent eval +# ii) func_quote_arg_unquoted_result +# has all characters that are still active within double +# quotes backslashified. Available only if 'unquoted' is specified. +# +# Available modes: +# ---------------- +# 'eval' (default) +# - escape shell special characters +# 'expand' +# - the same as 'eval'; but do not quote variable references +# 'pretty' +# - request aesthetic output, i.e. '"a b"' instead of 'a\ b'. This might +# be used later in func_quote to get output like: 'echo "a b"' instead +# of 'echo a\ b'. This is slower than default on some shells. +# 'unquoted' +# - produce also $func_quote_arg_unquoted_result which does not contain +# wrapping double-quotes. +# +# Examples for 'func_quote_arg pretty,unquoted string': +# +# string | *_result | *_unquoted_result +# ------------+-----------------------+------------------- +# " | \" | \" +# a b | "a b" | a b +# "a b" | "\"a b\"" | \"a b\" +# * | "*" | * +# z="${x-$y}" | "z=\"\${x-\$y}\"" | z=\"\${x-\$y}\" +# +# Examples for 'func_quote_arg pretty,unquoted,expand string': +# +# string | *_result | *_unquoted_result +# --------------+---------------------+-------------------- +# z="${x-$y}" | "z=\"${x-$y}\"" | z=\"${x-$y}\" +func_quote_arg () +{ + _G_quote_expand=false + case ,$1, in + *,expand,*) + _G_quote_expand=: + ;; esac - case $_G_arg in - # Double-quote args containing shell metacharacters to delay - # word splitting and command substitution for a subsequent eval. - # Many Bourne shells cannot handle close brackets correctly - # in scan sets, so we specify it separately. - *[\[\~\#\^\&\*\(\)\{\}\|\;\<\>\?\'\ \ ]*|*]*|"") - _G_arg=\"$_G_arg\" + case ,$1, in + *,pretty,*|*,expand,*|*,unquoted,*) + func_quote_portable $_G_quote_expand "$2" + func_quote_arg_result=$func_quote_portable_result + func_quote_arg_unquoted_result=$func_quote_portable_unquoted_result + ;; + *) + # Faster quote-for-eval for some shells. + func_quotefast_eval "$2" + func_quote_arg_result=$func_quotefast_eval_result ;; esac +} + - func_quote_for_expand_result=$_G_arg +# func_quote MODEs ARGs... +# ------------------------ +# Quote all ARGs to be evaled later and join them into single command. See +# func_quote_arg's description for more info. +func_quote () +{ + $debug_cmd + _G_func_quote_mode=$1 ; shift + func_quote_result= + while test 0 -lt $#; do + func_quote_arg "$_G_func_quote_mode" "$1" + if test -n "$func_quote_result"; then + func_append func_quote_result " $func_quote_arg_result" + else + func_append func_quote_result "$func_quote_arg_result" + fi + shift + done } @@ -1215,8 +1376,8 @@ func_show_eval () _G_cmd=$1 _G_fail_exp=${2-':'} - func_quote_for_expand "$_G_cmd" - eval "func_notquiet $func_quote_for_expand_result" + func_quote_arg pretty,expand "$_G_cmd" + eval "func_notquiet $func_quote_arg_result" $opt_dry_run || { eval "$_G_cmd" @@ -1241,8 +1402,8 @@ func_show_eval_locale () _G_fail_exp=${2-':'} $opt_quiet || { - func_quote_for_expand "$_G_cmd" - eval "func_echo $func_quote_for_expand_result" + func_quote_arg expand,pretty "$_G_cmd" + eval "func_echo $func_quote_arg_result" } $opt_dry_run || { @@ -1369,30 +1530,26 @@ func_lt_ver () # End: #! /bin/sh -# Set a version string for this script. -scriptversion=2014-01-07.03; # UTC - # A portable, pluggable option parser for Bourne shell. # Written by Gary V. Vaughan, 2010 -# Copyright (C) 2010-2015 Free Software Foundation, Inc. -# This is free software; see the source for copying conditions. There is NO -# warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. - -# 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. +# This is free software. There is NO warranty; not even for +# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. +# +# Copyright (C) 2010-2019, 2021, 2023-2024 Bootstrap Authors +# +# This file is dual licensed under the terms of the MIT license +# , and GPL version 2 or later +# . You must apply one of +# these licenses when using or redistributing this software or any of +# the files within it. See the URLs above, or the file `LICENSE` +# included in the Bootstrap distribution for the full license texts. -# You should have received a copy of the GNU General Public License -# along with this program. If not, see . +# Please report bugs or propose patches to: +# -# Please report bugs or propose patches to gary@gnu.org. +# Set a version string for this script. +scriptversion=2019-02-19.15; # UTC ## ------ ## @@ -1415,7 +1572,7 @@ scriptversion=2014-01-07.03; # UTC # # In order for the '--version' option to work, you will need to have a # suitably formatted comment like the one at the top of this file -# starting with '# Written by ' and ending with '# warranty; '. +# starting with '# Written by ' and ending with '# Copyright'. # # For '-h' and '--help' to work, you will also need a one line # description of your script's purpose in a comment directly above the @@ -1427,7 +1584,7 @@ scriptversion=2014-01-07.03; # UTC # to display verbose messages only when your user has specified # '--verbose'. # -# After sourcing this file, you can plug processing for additional +# After sourcing this file, you can plug in processing for additional # options by amending the variables from the 'Configuration' section # below, and following the instructions in the 'Option parsing' # section further down. @@ -1476,8 +1633,8 @@ fatal_help="Try '\$progname --help' for ## ------------------------- ## # This section contains functions for adding, removing, and running hooks -# to the main code. A hook is just a named list of of function, that can -# be run in order later on. +# in the main code. A hook is just a list of function names that can be +# run in order later on. # func_hookable FUNC_NAME # ----------------------- @@ -1510,7 +1667,8 @@ func_add_hook () # func_remove_hook FUNC_NAME HOOK_FUNC # ------------------------------------ -# Remove HOOK_FUNC from the list of functions called by FUNC_NAME. +# Remove HOOK_FUNC from the list of hook functions to be called by +# FUNC_NAME. func_remove_hook () { $debug_cmd @@ -1519,10 +1677,28 @@ func_remove_hook () } +# func_propagate_result FUNC_NAME_A FUNC_NAME_B +# --------------------------------------------- +# If the *_result variable of FUNC_NAME_A _is set_, assign its value to +# *_result variable of FUNC_NAME_B. +func_propagate_result () +{ + $debug_cmd + + func_propagate_result_result=: + if eval "test \"\${${1}_result+set}\" = set" + then + eval "${2}_result=\$${1}_result" + else + func_propagate_result_result=false + fi +} + + # func_run_hooks FUNC_NAME [ARG]... # --------------------------------- # Run all hook functions registered to FUNC_NAME. -# It is assumed that the list of hook functions contains nothing more +# It's assumed that the list of hook functions contains nothing more # than a whitespace-delimited list of legal shell function names, and # no effort is wasted trying to catch shell meta-characters or preserve # whitespace. @@ -1532,22 +1708,19 @@ func_run_hooks () case " $hookable_fns " in *" $1 "*) ;; - *) func_fatal_error "'$1' does not support hook funcions.n" ;; + *) func_fatal_error "'$1' does not support hook functions." ;; esac eval _G_hook_fns=\$$1_hooks; shift for _G_hook in $_G_hook_fns; do - eval $_G_hook '"$@"' - - # store returned options list back into positional - # parameters for next 'cmd' execution. - eval _G_hook_result=\$${_G_hook}_result - eval set dummy "$_G_hook_result"; shift + func_unset "${_G_hook}_result" + eval $_G_hook '${1+"$@"}' + func_propagate_result $_G_hook func_run_hooks + if $func_propagate_result_result; then + eval set dummy "$func_run_hooks_result"; shift + fi done - - func_quote_for_eval ${1+"$@"} - func_run_hooks_result=$func_quote_for_eval_result } @@ -1557,10 +1730,18 @@ func_run_hooks () ## --------------- ## # In order to add your own option parsing hooks, you must accept the -# full positional parameter list in your hook function, remove any -# options that you action, and then pass back the remaining unprocessed -# options in '_result', escaped suitably for -# 'eval'. Like this: +# full positional parameter list from your hook function. You may remove +# or edit any options that you action, and then pass back the remaining +# unprocessed options in '_result', escaped +# suitably for 'eval'. +# +# The '_result' variable is automatically unset +# before your hook gets called; for best performance, only set the +# *_result variable when necessary (i.e. don't call the 'func_quote' +# function unnecessarily because it can be an expensive operation on some +# machines). +# +# Like this: # # my_options_prep () # { @@ -1570,9 +1751,8 @@ func_run_hooks () # usage_message=$usage_message' # -s, --silent don'\''t print informational messages # ' -# -# func_quote_for_eval ${1+"$@"} -# my_options_prep_result=$func_quote_for_eval_result +# # No change in '$@' (ignored completely by this hook). Leave +# # my_options_prep_result variable intact. # } # func_add_hook func_options_prep my_options_prep # @@ -1581,25 +1761,36 @@ func_run_hooks () # { # $debug_cmd # -# # Note that for efficiency, we parse as many options as we can +# args_changed=false +# +# # Note that, for efficiency, we parse as many options as we can # # recognise in a loop before passing the remainder back to the # # caller on the first unrecognised argument we encounter. # while test $# -gt 0; do # opt=$1; shift # case $opt in -# --silent|-s) opt_silent=: ;; +# --silent|-s) opt_silent=: +# args_changed=: +# ;; # # Separate non-argument short options: # -s*) func_split_short_opt "$_G_opt" # set dummy "$func_split_short_opt_name" \ # "-$func_split_short_opt_arg" ${1+"$@"} # shift +# args_changed=: # ;; -# *) set dummy "$_G_opt" "$*"; shift; break ;; +# *) # Make sure the first unrecognised option "$_G_opt" +# # is added back to "$@" in case we need it later, +# # if $args_changed was set to 'true'. +# set dummy "$_G_opt" ${1+"$@"}; shift; break ;; # esac # done # -# func_quote_for_eval ${1+"$@"} -# my_silent_option_result=$func_quote_for_eval_result +# # Only call 'func_quote' here if we processed at least one argument. +# if $args_changed; then +# func_quote eval ${1+"$@"} +# my_silent_option_result=$func_quote_result +# fi # } # func_add_hook func_parse_options my_silent_option # @@ -1610,17 +1801,26 @@ func_run_hooks () # # $opt_silent && $opt_verbose && func_fatal_help "\ # '--silent' and '--verbose' options are mutually exclusive." -# -# func_quote_for_eval ${1+"$@"} -# my_option_validation_result=$func_quote_for_eval_result # } # func_add_hook func_validate_options my_option_validation # -# You'll alse need to manually amend $usage_message to reflect the extra +# You'll also need to manually amend $usage_message to reflect the extra # options you parse. It's preferable to append if you can, so that # multiple option parsing hooks can be added safely. +# func_options_finish [ARG]... +# ---------------------------- +# Finishing the option parse loop (call 'func_options' hooks ATM). +func_options_finish () +{ + $debug_cmd + + func_run_hooks func_options ${1+"$@"} + func_propagate_result func_run_hooks func_options_finish +} + + # func_options [ARG]... # --------------------- # All the functions called inside func_options are hookable. See the @@ -1630,17 +1830,27 @@ func_options () { $debug_cmd - func_options_prep ${1+"$@"} - eval func_parse_options \ - ${func_options_prep_result+"$func_options_prep_result"} - eval func_validate_options \ - ${func_parse_options_result+"$func_parse_options_result"} + _G_options_quoted=false - eval func_run_hooks func_options \ - ${func_validate_options_result+"$func_validate_options_result"} + for my_func in options_prep parse_options validate_options options_finish + do + func_unset func_${my_func}_result + func_unset func_run_hooks_result + eval func_$my_func '${1+"$@"}' + func_propagate_result func_$my_func func_options + if $func_propagate_result_result; then + eval set dummy "$func_options_result"; shift + _G_options_quoted=: + fi + done - # save modified positional parameters for caller - func_options_result=$func_run_hooks_result + $_G_options_quoted || { + # As we (func_options) are top-level options-parser function and + # nobody quoted "$@" for us yet, we need to do it explicitly for + # caller. + func_quote eval ${1+"$@"} + func_options_result=$func_quote_result + } } @@ -1649,9 +1859,8 @@ func_options () # All initialisations required before starting the option parse loop. # Note that when calling hook functions, we pass through the list of # positional parameters. If a hook function modifies that list, and -# needs to propogate that back to rest of this script, then the complete -# modified list must be put in 'func_run_hooks_result' before -# returning. +# needs to propagate that back to rest of this script, then the complete +# modified list must be put in 'func_run_hooks_result' before returning. func_hookable func_options_prep func_options_prep () { @@ -1662,9 +1871,7 @@ func_options_prep () opt_warning_types= func_run_hooks func_options_prep ${1+"$@"} - - # save modified positional parameters for caller - func_options_prep_result=$func_run_hooks_result + func_propagate_result func_run_hooks func_options_prep } @@ -1676,25 +1883,32 @@ func_parse_options () { $debug_cmd - func_parse_options_result= - + _G_parse_options_requote=false # this just eases exit handling while test $# -gt 0; do # Defer to hook functions for initial option parsing, so they # get priority in the event of reusing an option name. func_run_hooks func_parse_options ${1+"$@"} - - # Adjust func_parse_options positional parameters to match - eval set dummy "$func_run_hooks_result"; shift + func_propagate_result func_run_hooks func_parse_options + if $func_propagate_result_result; then + eval set dummy "$func_parse_options_result"; shift + # Even though we may have changed "$@", we passed the "$@" array + # down into the hook and it quoted it for us (because we are in + # this if-branch). No need to quote it again. + _G_parse_options_requote=false + fi # Break out of the loop if we already parsed every option. test $# -gt 0 || break + # We expect that one of the options parsed in this function matches + # and thus we remove _G_opt from "$@" and need to re-quote. + _G_match_parse_options=: _G_opt=$1 shift case $_G_opt in --debug|-x) debug_cmd='set -x' - func_echo "enabling shell trace mode" + func_echo "enabling shell trace mode" >&2 $debug_cmd ;; @@ -1704,7 +1918,10 @@ func_parse_options () ;; --warnings|--warning|-W) - test $# = 0 && func_missing_arg $_G_opt && break + if test $# = 0 && func_missing_arg $_G_opt; then + _G_parse_options_requote=: + break + fi case " $warning_categories $1" in *" $1 "*) # trailing space prevents matching last $1 above @@ -1757,15 +1974,24 @@ func_parse_options () shift ;; - --) break ;; + --) _G_parse_options_requote=: ; break ;; -*) func_fatal_help "unrecognised option: '$_G_opt'" ;; - *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + *) set dummy "$_G_opt" ${1+"$@"}; shift + _G_match_parse_options=false + break + ;; esac + + if $_G_match_parse_options; then + _G_parse_options_requote=: + fi done - # save modified positional parameters for caller - func_quote_for_eval ${1+"$@"} - func_parse_options_result=$func_quote_for_eval_result + if $_G_parse_options_requote; then + # save modified positional parameters for caller + func_quote eval ${1+"$@"} + func_parse_options_result=$func_quote_result + fi } @@ -1782,12 +2008,10 @@ func_validate_options () test -n "$opt_warning_types" || opt_warning_types=" $warning_categories" func_run_hooks func_validate_options ${1+"$@"} + func_propagate_result func_run_hooks func_validate_options # Bail if the options were screwed! $exit_cmd $EXIT_FAILURE - - # save modified positional parameters for caller - func_validate_options_result=$func_run_hooks_result } @@ -1843,8 +2067,8 @@ func_missing_arg () # func_split_equals STRING # ------------------------ -# Set func_split_equals_lhs and func_split_equals_rhs shell variables after -# splitting STRING at the '=' sign. +# Set func_split_equals_lhs and func_split_equals_rhs shell variables +# after splitting STRING at the '=' sign. test -z "$_G_HAVE_XSI_OPS" \ && (eval 'x=a/b/c; test 5aa/bb/cc = "${#x}${x%%/*}${x%/*}${x#*/}${x##*/}"') 2>/dev/null \ @@ -1859,8 +2083,9 @@ then func_split_equals_lhs=${1%%=*} func_split_equals_rhs=${1#*=} - test "x$func_split_equals_lhs" = "x$1" \ - && func_split_equals_rhs= + if test "x$func_split_equals_lhs" = "x$1"; then + func_split_equals_rhs= + fi }' else # ...otherwise fall back to using expr, which is often a shell builtin. @@ -1870,7 +2095,7 @@ else func_split_equals_lhs=`expr "x$1" : 'x\([^=]*\)'` func_split_equals_rhs= - test "x$func_split_equals_lhs" = "x$1" \ + test "x$func_split_equals_lhs=" = "x$1" \ || func_split_equals_rhs=`expr "x$1" : 'x[^=]*=\(.*\)$'` } fi #func_split_equals @@ -1896,7 +2121,7 @@ else { $debug_cmd - func_split_short_opt_name=`expr "x$1" : 'x-\(.\)'` + func_split_short_opt_name=`expr "x$1" : 'x\(-.\)'` func_split_short_opt_arg=`expr "x$1" : 'x-.\(.*\)$'` } fi #func_split_short_opt @@ -1938,31 +2163,44 @@ func_usage_message () # func_version # ------------ # Echo version message to standard output and exit. +# The version message is extracted from the calling file's header +# comments, with leading '# ' stripped: +# 1. First display the progname and version +# 2. Followed by the header comment line matching /^# Written by / +# 3. Then a blank line followed by the first following line matching +# /^# Copyright / +# 4. Immediately followed by any lines between the previous matches, +# except lines preceding the intervening completely blank line. +# For example, see the header comments of this file. func_version () { $debug_cmd printf '%s\n' "$progname $scriptversion" $SED -n ' - /(C)/!b go - :more - /\./!{ - N - s|\n# | | - b more - } - :go - /^# Written by /,/# warranty; / { - s|^# || - s|^# *$|| - s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| - p + /^# Written by /!b + s|^# ||; p; n + + :fwd2blnk + /./ { + n + b fwd2blnk } - /^# Written by / { - s|^# || - p + p; n + + :holdwrnt + s|^# || + s|^# *$|| + /^Copyright /!{ + /./H + n + b holdwrnt } - /^warranty; /q' < "$progpath" + + s|\((C)\)[ 0-9,-]*[ ,-]\([1-9][0-9]* \)|\1 \2| + G + s|\(\n\)\n*|\1|g + p; q' < "$progpath" exit $? } @@ -1972,12 +2210,35 @@ func_version () # mode: shell-script # sh-indentation: 2 # eval: (add-hook 'before-save-hook 'time-stamp) -# time-stamp-pattern: "10/scriptversion=%:y-%02m-%02d.%02H; # UTC" +# time-stamp-pattern: "30/scriptversion=%:y-%02m-%02d.%02H; # UTC" # time-stamp-time-zone: "UTC" # End: # Set a version string. -scriptversion='(GNU libtool) 2.4.6' +scriptversion='(GNU libtool) 2.5.4' + +# func_version +# ------------ +# Echo version message to standard output and exit. +func_version () +{ + $debug_cmd + + year=`date +%Y` + + cat < +This is free software: you are free to change and redistribute it. +There is NO WARRANTY, to the extent permitted by law. + +Originally written by Gordon Matzigkeit, 1996 +(See AUTHORS for complete contributor listing) +EOF + + exit $? +} # func_echo ARG... @@ -2000,18 +2261,6 @@ func_echo () } -# func_warning ARG... -# ------------------- -# Libtool warnings are not categorized, so override funclib.sh -# func_warning with this simpler definition. -func_warning () -{ - $debug_cmd - - $warning_func ${1+"$@"} -} - - ## ---------------- ## ## Options parsing. ## ## ---------------- ## @@ -2023,19 +2272,23 @@ usage='$progpath [OPTION]... [MODE-ARG]. # Short help message in response to '-h'. usage_message="Options: - --config show all configuration variables - --debug enable verbose shell tracing - -n, --dry-run display commands without modifying any files - --features display basic configuration information and exit - --mode=MODE use operation mode MODE - --no-warnings equivalent to '-Wnone' - --preserve-dup-deps don't remove duplicate dependency libraries - --quiet, --silent don't print informational messages - --tag=TAG use configuration variables from tag TAG - -v, --verbose print more informational messages than default - --version print version information - -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] - -h, --help, --help-all print short, long, or detailed help message + --config show all configuration variables + --debug enable verbose shell tracing + -n, --dry-run display commands without modifying any files + --features display basic configuration information + --finish use operation '--mode=finish' + --mode=MODE use operation mode MODE + --no-finish don't update shared library cache + --no-quiet, --no-silent print default informational messages + --no-warnings equivalent to '-Wnone' + --preserve-dup-deps don't remove duplicate dependency libraries + --quiet, --silent don't print informational messages + --reorder-cache=DIRS reorder shared library cache for preferred DIRS + --tag=TAG use configuration variables from tag TAG + -v, --verbose print more informational messages than default + --version print version information + -W, --warnings=CATEGORY report the warnings falling in CATEGORY [all] + -h, --help, --help-all print short, long, or detailed help message " # Additional text appended to 'usage_message' in response to '--help'. @@ -2068,13 +2321,13 @@ include the following information: compiler: $LTCC compiler flags: $LTCFLAGS linker: $LD (gnu? $with_gnu_ld) - version: $progname (GNU libtool) 2.4.6 + version: $progname $scriptversion automake: `($AUTOMAKE --version) 2>/dev/null |$SED 1q` autoconf: `($AUTOCONF --version) 2>/dev/null |$SED 1q` Report bugs to . -GNU libtool home page: . -General help using GNU software: ." +GNU libtool home page: . +General help using GNU software: ." exit 0 } @@ -2264,12 +2517,17 @@ libtool_options_prep () opt_dry_run=false opt_help=false opt_mode= + opt_reorder_cache=false opt_preserve_dup_deps=false opt_quiet=false + opt_finishing=true + opt_warning= nonopt= preserve_args= + _G_rc_lt_options_prep=: + # Shorthand for --mode=foo, only valid as the first argument case $1 in clean|clea|cle|cl) @@ -2293,11 +2551,16 @@ libtool_options_prep () uninstall|uninstal|uninsta|uninst|unins|unin|uni|un|u) shift; set dummy --mode uninstall ${1+"$@"}; shift ;; + *) + _G_rc_lt_options_prep=false + ;; esac - # Pass back the list of options. - func_quote_for_eval ${1+"$@"} - libtool_options_prep_result=$func_quote_for_eval_result + if $_G_rc_lt_options_prep; then + # Pass back the list of options. + func_quote eval ${1+"$@"} + libtool_options_prep_result=$func_quote_result + fi } func_add_hook func_options_prep libtool_options_prep @@ -2309,9 +2572,12 @@ libtool_parse_options () { $debug_cmd + _G_rc_lt_parse_options=false + # Perform our own loop to consume as many options as possible in # each iteration. while test $# -gt 0; do + _G_match_lt_parse_options=: _G_opt=$1 shift case $_G_opt in @@ -2345,14 +2611,18 @@ libtool_parse_options () clean|compile|execute|finish|install|link|relink|uninstall) ;; # Catch anything else as an error - *) func_error "invalid argument for $_G_opt" + *) func_error "invalid argument '$1' for $_G_opt" exit_cmd=exit - break ;; esac shift ;; + --no-finish) + opt_finishing=false + func_append preserve_args " $_G_opt" + ;; + --no-silent|--no-quiet) opt_quiet=false func_append preserve_args " $_G_opt" @@ -2368,6 +2638,24 @@ libtool_parse_options () func_append preserve_args " $_G_opt" ;; + --reorder-cache) + opt_reorder_cache=true + shared_lib_dirs=$1 + if test -n "$shared_lib_dirs"; then + case $1 in + # Must begin with /: + /*) ;; + + # Catch anything else as an error (relative paths) + *) func_error "invalid argument '$1' for $_G_opt" + func_error "absolute paths are required for $_G_opt" + exit_cmd=exit + ;; + esac + fi + shift + ;; + --silent|--quiet) opt_quiet=: opt_verbose=false @@ -2386,19 +2674,36 @@ libtool_parse_options () func_append preserve_args " $_G_opt" ;; - # An option not handled by this hook function: - *) set dummy "$_G_opt" ${1+"$@"}; shift; break ;; + # An option not handled by this hook function: + *) set dummy "$_G_opt" ${1+"$@"} ; shift + _G_match_lt_parse_options=false + break + ;; esac + $_G_match_lt_parse_options && _G_rc_lt_parse_options=: done - - # save modified positional parameters for caller - func_quote_for_eval ${1+"$@"} - libtool_parse_options_result=$func_quote_for_eval_result + if $_G_rc_lt_parse_options; then + # save modified positional parameters for caller + func_quote eval ${1+"$@"} + libtool_parse_options_result=$func_quote_result + fi } func_add_hook func_parse_options libtool_parse_options +# func_warning ARG... +# ------------------- +# Libtool warnings are not categorized, so override funclib.sh +# func_warning with this simpler definition. +func_warning () +{ + if $opt_warning; then + $debug_cmd + $warning_func ${1+"$@"} + fi +} + # libtool_validate_options [ARG]... # --------------------------------- @@ -2415,17 +2720,10 @@ libtool_validate_options () # preserve --debug test : = "$debug_cmd" || func_append preserve_args " --debug" - case $host in - # Solaris2 added to fix http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16452 - # see also: http://gcc.gnu.org/bugzilla/show_bug.cgi?id=59788 - *cygwin* | *mingw* | *pw32* | *cegcc* | *solaris2* | *os2*) - # don't eliminate duplications in $postdeps and $predeps - opt_duplicate_compiler_generated_deps=: - ;; - *) - opt_duplicate_compiler_generated_deps=$opt_preserve_dup_deps - ;; - esac + # Keeping compiler generated duplicates in $postdeps and $predeps is not + # harmful, and is necessary in a majority of systems that use it to satisfy + # symbol dependencies. + opt_duplicate_compiler_generated_deps=: $opt_help || { # Sanity checks first: @@ -2451,8 +2749,8 @@ libtool_validate_options () } # Pass back the unparsed argument list - func_quote_for_eval ${1+"$@"} - libtool_validate_options_result=$func_quote_for_eval_result + func_quote eval ${1+"$@"} + libtool_validate_options_result=$func_quote_result } func_add_hook func_validate_options libtool_validate_options @@ -2750,7 +3048,7 @@ EOF # func_convert_core_file_wine_to_w32 ARG # Helper function used by file name conversion functions when $build is *nix, -# and $host is mingw, cygwin, or some other w32 environment. Relies on a +# and $host is mingw, windows, cygwin, or some other w32 environment. Relies on a # correctly configured wine environment available, with the winepath program # in $build's $PATH. # @@ -2782,9 +3080,10 @@ func_convert_core_file_wine_to_w32 () # func_convert_core_path_wine_to_w32 ARG # Helper function used by path conversion functions when $build is *nix, and -# $host is mingw, cygwin, or some other w32 environment. Relies on a correctly -# configured wine environment available, with the winepath program in $build's -# $PATH. Assumes ARG has no leading or trailing path separator characters. +# $host is mingw, windows, cygwin, or some other w32 environment. Relies on a +# correctly configured wine environment available, with the winepath program +# in $build's $PATH. Assumes ARG has no leading or trailing path separator +# characters. # # ARG is path to be converted from $build format to win32. # Result is available in $func_convert_core_path_wine_to_w32_result. @@ -2927,6 +3226,15 @@ func_convert_path_front_back_pathsep () # end func_convert_path_front_back_pathsep +# func_convert_delimited_path PATH ORIG_DELIMITER NEW_DELIMITER +# Replaces a delimiter for a given path. +func_convert_delimited_path () +{ + converted_path=`$ECHO "$1" | $SED "s#$2#$3#g"` +} +# end func_convert_delimited_path + + ################################################## # $build to $host FILE NAME CONVERSION FUNCTIONS # ################################################## @@ -3261,6 +3569,65 @@ func_dll_def_p () } +# func_reorder_shared_lib_cache DIRS +# Reorder the shared library cache by unconfiguring previous shared library cache +# and configuring preferred search directories before previous search directories. +# Previous shared library cache: /usr/lib /usr/local/lib +# Preferred search directories: /tmp/testing +# Reordered shared library cache: /tmp/testing /usr/lib /usr/local/lib +func_reorder_shared_lib_cache () +{ + $debug_cmd + + case $host_os in + openbsd*) + get_search_directories=`PATH="$PATH:/sbin" ldconfig -r | $GREP "search directories" | $SED "s#.*search directories:\ ##g"` + func_convert_delimited_path "$get_search_directories" ':' '\ ' + save_search_directories=$converted_path + func_convert_delimited_path "$1" ':' '\ ' + + # Ensure directories exist + for dir in $converted_path; do + # Ensure each directory is an absolute path + case $dir in + /*) ;; + *) func_error "Directory '$dir' is not an absolute path" + exit $EXIT_FAILURE ;; + esac + # Ensure no trailing slashes + func_stripname '' '/' "$dir" + dir=$func_stripname_result + if test -d "$dir"; then + if test -n "$preferred_search_directories"; then + preferred_search_directories="$preferred_search_directories $dir" + else + preferred_search_directories=$dir + fi + else + func_error "Directory '$dir' does not exist" + exit $EXIT_FAILURE + fi + done + + PATH="$PATH:/sbin" ldconfig -U $save_search_directories + PATH="$PATH:/sbin" ldconfig -m $preferred_search_directories $save_search_directories + get_search_directories=`PATH="$PATH:/sbin" ldconfig -r | $GREP "search directories" | $SED "s#.*search directories:\ ##g"` + func_convert_delimited_path "$get_search_directories" ':' '\ ' + reordered_search_directories=$converted_path + + $ECHO "Original: $save_search_directories" + $ECHO "Reordered: $reordered_search_directories" + exit $EXIT_SUCCESS + ;; + *) + func_error "--reorder-cache is not supported for host_os=$host_os." + exit $EXIT_FAILURE + ;; + esac +} +# end func_reorder_shared_lib_cache + + # func_mode_compile arg... func_mode_compile () { @@ -3418,8 +3785,8 @@ func_mode_compile () esac done - func_quote_for_eval "$libobj" - test "X$libobj" != "X$func_quote_for_eval_result" \ + func_quote_arg pretty "$libobj" + test "X$libobj" != "X$func_quote_arg_result" \ && $ECHO "X$libobj" | $GREP '[]~#^*{};<>?"'"'"' &()|`$[]' \ && func_warning "libobj name '$libobj' may not contain shell special characters." func_dirname_and_basename "$obj" "/" "" @@ -3439,7 +3806,7 @@ func_mode_compile () # On Cygwin there's no "real" PIC flag so we must build both object types case $host_os in - cygwin* | mingw* | pw32* | os2* | cegcc*) + cygwin* | mingw* | windows* | pw32* | os2* | cegcc*) pic_mode=default ;; esac @@ -3492,8 +3859,8 @@ compiler." func_to_tool_file "$srcfile" func_convert_file_msys_to_w32 srcfile=$func_to_tool_file_result - func_quote_for_eval "$srcfile" - qsrcfile=$func_quote_for_eval_result + func_quote_arg pretty "$srcfile" + qsrcfile=$func_quote_arg_result # Only build a PIC object if we are building libtool libraries. if test yes = "$build_libtool_libs"; then @@ -3648,7 +4015,8 @@ This mode accepts the following addition -prefer-non-pic try to build non-PIC objects only -shared do not build a '.o' file suitable for static linking -static only build a '.o' file suitable for static linking - -Wc,FLAG pass FLAG directly to the compiler + -Wc,FLAG + -Xcompiler FLAG pass FLAG directly to the compiler COMPILE-COMMAND is a command to be used in creating a 'standard' object file from the given SOURCEFILE. @@ -3754,6 +4122,8 @@ The following components of LINK-COMMAND -weak LIBNAME declare that the target provides the LIBNAME interface -Wc,FLAG -Xcompiler FLAG pass linker-specific FLAG directly to the compiler + -Wa,FLAG + -Xassembler FLAG pass linker-specific FLAG directly to the assembler -Wl,FLAG -Xlinker FLAG pass linker-specific FLAG directly to the linker -XCClinker FLAG pass link-specific FLAG to the compiler driver (CC) @@ -3830,6 +4200,12 @@ if $opt_help; then fi +# If option '--reorder-cache', reorder the shared library cache and exit. +if $opt_reorder_cache; then + func_reorder_shared_lib_cache $shared_lib_dirs +fi + + # func_mode_execute arg... func_mode_execute () { @@ -4014,7 +4390,7 @@ func_mode_finish () fi fi - if test -n "$finish_cmds$finish_eval" && test -n "$libdirs"; then + if test -n "$finish_cmds$finish_eval" && test -n "$libdirs" && $opt_finishing; then for libdir in $libdirs; do if test -n "$finish_cmds"; then # Do each command in the finish commands. @@ -4039,6 +4415,12 @@ func_mode_finish () for libdir in $libdirs; do $ECHO " $libdir" done + if test "false" = "$opt_finishing"; then + echo + echo "NOTE: finish_cmds were not executed during testing, so you must" + echo "manually run ldconfig to add a given test directory, LIBDIR, to" + echo "the search path for generated executables." + fi echo echo "If you ever happen to want to link against installed libraries" echo "in a given directory, LIBDIR, you must either use libtool, and" @@ -4096,8 +4478,8 @@ func_mode_install () case $nonopt in *shtool*) :;; *) false;; esac then # Aesthetically quote it. - func_quote_for_eval "$nonopt" - install_prog="$func_quote_for_eval_result " + func_quote_arg pretty "$nonopt" + install_prog="$func_quote_arg_result " arg=$1 shift else @@ -4107,8 +4489,8 @@ func_mode_install () # The real first argument should be the name of the installation program. # Aesthetically quote it. - func_quote_for_eval "$arg" - func_append install_prog "$func_quote_for_eval_result" + func_quote_arg pretty "$arg" + func_append install_prog "$func_quote_arg_result" install_shared_prog=$install_prog case " $install_prog " in *[\\\ /]cp\ *) install_cp=: ;; @@ -4165,12 +4547,12 @@ func_mode_install () esac # Aesthetically quote the argument. - func_quote_for_eval "$arg" - func_append install_prog " $func_quote_for_eval_result" + func_quote_arg pretty "$arg" + func_append install_prog " $func_quote_arg_result" if test -n "$arg2"; then - func_quote_for_eval "$arg2" + func_quote_arg pretty "$arg2" fi - func_append install_shared_prog " $func_quote_for_eval_result" + func_append install_shared_prog " $func_quote_arg_result" done test -z "$install_prog" && \ @@ -4181,8 +4563,8 @@ func_mode_install () if test -n "$install_override_mode" && $no_mode; then if $install_cp; then :; else - func_quote_for_eval "$install_override_mode" - func_append install_shared_prog " -m $func_quote_for_eval_result" + func_quote_arg pretty "$install_override_mode" + func_append install_shared_prog " -m $func_quote_arg_result" fi fi @@ -4275,8 +4657,15 @@ func_mode_install () func_append dir "$objdir" if test -n "$relink_command"; then + # Strip any trailing slash from the destination. + func_stripname '' '/' "$libdir" + destlibdir=$func_stripname_result + + func_stripname '' '/' "$destdir" + s_destdir=$func_stripname_result + # Determine the prefix the user has applied to our future dir. - inst_prefix_dir=`$ECHO "$destdir" | $SED -e "s%$libdir\$%%"` + inst_prefix_dir=`$ECHO "X$s_destdir" | $Xsed -e "s%$destlibdir\$%%"` # Don't allow the user to place us outside of our expected # location b/c this prevents finding dependent libraries that @@ -4313,7 +4702,7 @@ func_mode_install () 'exit $?' tstripme=$stripme case $host_os in - cygwin* | mingw* | pw32* | cegcc*) + cygwin* | mingw* | windows* | pw32* | cegcc*) case $realname in *.dll.a) tstripme= @@ -4426,7 +4815,7 @@ func_mode_install () # Do a test to see if this is really a libtool program. case $host in - *cygwin* | *mingw*) + *cygwin* | *mingw* | *windows*) if func_ltwrapper_executable_p "$file"; then func_ltwrapper_scriptname "$file" wrapper=$func_ltwrapper_scriptname_result @@ -4478,8 +4867,8 @@ func_mode_install () relink_command=`$ECHO "$relink_command" | $SED 's%@OUTPUT@%'"$outputname"'%g'` $opt_quiet || { - func_quote_for_expand "$relink_command" - eval "func_echo $func_quote_for_expand_result" + func_quote_arg expand,pretty "$relink_command" + eval "func_echo $func_quote_arg_result" } if eval "$relink_command"; then : else @@ -4654,7 +5043,7 @@ extern \"C\" { $RM $export_symbols eval "$SED -n -e '/^: @PROGRAM@ $/d' -e 's/^.* \(.*\)$/\1/p' "'< "$nlist" > "$export_symbols"' case $host in - *cygwin* | *mingw* | *cegcc* ) + *cygwin* | *mingw* | *windows* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$export_symbols" >> "$output_objdir/$outputname.def"' ;; @@ -4666,7 +5055,7 @@ extern \"C\" { eval '$GREP -f "$output_objdir/$outputname.exp" < "$nlist" > "$nlist"T' eval '$MV "$nlist"T "$nlist"' case $host in - *cygwin* | *mingw* | *cegcc* ) + *cygwin* | *mingw* | *windows* | *cegcc* ) eval "echo EXPORTS "'> "$output_objdir/$outputname.def"' eval 'cat "$nlist" >> "$output_objdir/$outputname.def"' ;; @@ -4680,7 +5069,7 @@ extern \"C\" { func_basename "$dlprefile" name=$func_basename_result case $host in - *cygwin* | *mingw* | *cegcc* ) + *cygwin* | *mingw* | *windows* | *cegcc* ) # if an import library, we need to obtain dlname if func_win32_import_lib_p "$dlprefile"; then func_tr_sh "$dlprefile" @@ -4706,8 +5095,16 @@ extern \"C\" { eval '$ECHO ": $name " >> "$nlist"' fi func_to_tool_file "$dlprefile" func_convert_file_msys_to_w32 - eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | - $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + case $host in + i[3456]86-*-mingw32*) + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/_nm__//' >> '$nlist'" + ;; + *) + eval "$NM \"$func_to_tool_file_result\" 2>/dev/null | $global_symbol_pipe | + $SED -e '/I __imp/d' -e 's/I __nm_/D /;s/__nm_//' >> '$nlist'" + ;; + esac } else # not an import lib $opt_dry_run || { @@ -4855,7 +5252,7 @@ static const void *lt_preloaded_setup() # Transform the symbol file into the correct name. symfileobj=$output_objdir/${my_outputname}S.$objext case $host in - *cygwin* | *mingw* | *cegcc* ) + *cygwin* | *mingw* | *windows* | *cegcc* ) if test -f "$output_objdir/$my_outputname.def"; then compile_command=`$ECHO "$compile_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` finalize_command=`$ECHO "$finalize_command" | $SED "s%@SYMFILE@%$output_objdir/$my_outputname.def $symfileobj%"` @@ -4931,7 +5328,7 @@ func_win32_libid () *ar\ archive*) # could be an import, or static # Keep the egrep pattern in sync with the one in _LT_CHECK_MAGIC_METHOD. if eval $OBJDUMP -f $1 | $SED -e '10q' 2>/dev/null | - $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64)' >/dev/null; then + $EGREP 'file format (pei*-i386(.*architecture: i386)?|pe-arm-wince|pe-x86-64|pe-aarch64)' >/dev/null; then case $nm_interface in "MS dumpbin") if func_cygming_ms_implib_p "$1" || @@ -5198,7 +5595,7 @@ func_extract_archives () # # Emit a libtool wrapper script on stdout. # Don't directly open a file because we may want to -# incorporate the script contents within a cygwin/mingw +# incorporate the script contents within a cygwin/mingw/windows # wrapper executable. Must ONLY be called from within # func_mode_link because it depends on a number of variables # set therein. @@ -5206,7 +5603,7 @@ func_extract_archives () # ARG is the value that the WRAPPER_SCRIPT_BELONGS_IN_OBJDIR # variable will take. If 'yes', then the emitted script # will assume that the directory where it is stored is -# the $objdir directory. This is a cygwin/mingw-specific +# the $objdir directory. This is a cygwin/mingw/windows-specific # behavior. func_emit_wrapper () { @@ -5258,7 +5655,8 @@ else if test \"\$libtool_execute_magic\" != \"$magic\"; then file=\"\$0\"" - qECHO=`$ECHO "$ECHO" | $SED "$sed_quote_subst"` + func_quote_arg pretty "$ECHO" + qECHO=$func_quote_arg_result $ECHO "\ # A function that is used when there is no print builtin or printf. @@ -5268,7 +5666,7 @@ func_fallback_echo () \$1 _LTECHO_EOF' } - ECHO=\"$qECHO\" + ECHO=$qECHO fi # Very basic option parsing. These options are (a) specific to @@ -5330,7 +5728,7 @@ func_exec_program_core () " case $host in # Backslashes separate directories on plain windows - *-*-mingw | *-*-os2* | *-cegcc*) + *-*-mingw* | *-*-windows* | *-*-os2* | *-cegcc*) $ECHO "\ if test -n \"\$lt_option_debug\"; then \$ECHO \"$outputname:$output:\$LINENO: newargv[0]: \$progdir\\\\\$program\" 1>&2 @@ -5398,7 +5796,7 @@ func_exec_program () file=\`ls -ld \"\$thisdir/\$file\" | $SED -n 's/.*-> //p'\` done - # Usually 'no', except on cygwin/mingw when embedded into + # Usually 'no', except on cygwin/mingw/windows when embedded into # the cwrapper. WRAPPER_SCRIPT_BELONGS_IN_OBJDIR=$func_emit_wrapper_arg1 if test \"\$WRAPPER_SCRIPT_BELONGS_IN_OBJDIR\" = \"yes\"; then @@ -5530,7 +5928,7 @@ EOF #endif #include #include -#ifdef _MSC_VER +#if defined _WIN32 && !defined __GNUC__ # include # include # include @@ -5555,7 +5953,7 @@ EOF /* declarations of non-ANSI functions */ #if defined __MINGW32__ # ifdef __STRICT_ANSI__ -int _putenv (const char *); +_CRTIMP int __cdecl _putenv (const char *); # endif #elif defined __CYGWIN__ # ifdef __STRICT_ANSI__ @@ -5753,7 +6151,7 @@ main (int argc, char *argv[]) { EOF case $host in - *mingw* | *cygwin* ) + *mingw* | *windows* | *cygwin* ) # make stdout use "unix" line endings echo " setmode(1,_O_BINARY);" ;; @@ -5772,7 +6170,7 @@ EOF { /* however, if there is an option in the LTWRAPPER_OPTION_PREFIX namespace, but it is not one of the ones we know about and - have already dealt with, above (inluding dump-script), then + have already dealt with, above (including dump-script), then report an error. Otherwise, targets might begin to believe they are allowed to use options in the LTWRAPPER_OPTION_PREFIX namespace. The first time any user complains about this, we'll @@ -5856,7 +6254,7 @@ EOF EOF case $host_os in - mingw*) + mingw* | windows*) cat <<"EOF" { char* p; @@ -5898,7 +6296,7 @@ EOF EOF case $host_os in - mingw*) + mingw* | windows*) cat <<"EOF" /* execv doesn't actually work on mingw as expected on unix */ newargz = prepare_spawn (newargz); @@ -6317,7 +6715,7 @@ lt_update_lib_path (const char *name, co EOF case $host_os in - mingw*) + mingw* | windows*) cat <<"EOF" /* Prepares an argument vector before calling spawn(). @@ -6492,7 +6890,7 @@ func_mode_link () $debug_cmd case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*) # It is impossible to link a dll without this setting, and # we shouldn't force the makefile maintainer to figure out # what system we are compiling for in order to pass an extra @@ -6516,6 +6914,7 @@ func_mode_link () finalize_command=$nonopt compile_rpath= + compile_rpath_tail= finalize_rpath= compile_shlibpath= finalize_shlibpath= @@ -6556,10 +6955,12 @@ func_mode_link () xrpath= perm_rpath= temp_rpath= + temp_rpath_tail= thread_safe=no vinfo= vinfo_number=no weak_libs= + rpath_arg= single_module=$wl-single_module func_infer_tag $base_compile @@ -6611,9 +7012,9 @@ func_mode_link () while test "$#" -gt 0; do arg=$1 shift - func_quote_for_eval "$arg" - qarg=$func_quote_for_eval_unquoted_result - func_append libtool_args " $func_quote_for_eval_result" + func_quote_arg pretty,unquoted "$arg" + qarg=$func_quote_arg_unquoted_result + func_append libtool_args " $func_quote_arg_result" # If the previous option needs an argument, assign it. if test -n "$prev"; then @@ -6822,7 +7223,7 @@ func_mode_link () case $arg in [\\/]* | [A-Za-z]:[\\/]*) ;; *) - func_fatal_error "only absolute run-paths are allowed" + func_fatal_error "argument to -rpath is not absolute: $arg" ;; esac if test rpath = "$prev"; then @@ -6849,6 +7250,13 @@ func_mode_link () prev= continue ;; + xassembler) + func_append compiler_flags " -Xassembler $qarg" + prev= + func_append compile_command " -Xassembler $qarg" + func_append finalize_command " -Xassembler $qarg" + continue + ;; xcclinker) func_append linker_flags " $qarg" func_append compiler_flags " $qarg" @@ -6991,7 +7399,7 @@ func_mode_link () ;; esac case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-os2* | *-cegcc*) + *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-os2* | *-cegcc*) testbindir=`$ECHO "$dir" | $SED 's*/lib$*/bin*'` case :$dllsearchpath: in *":$dir:"*) ;; @@ -7011,7 +7419,7 @@ func_mode_link () -l*) if test X-lc = "X$arg" || test X-lm = "X$arg"; then case $host in - *-*-cygwin* | *-*-mingw* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) + *-*-cygwin* | *-*-mingw* | *-*-windows* | *-*-pw32* | *-*-beos* | *-cegcc* | *-*-haiku*) # These systems don't actually have a C or math library (as such) continue ;; @@ -7019,7 +7427,7 @@ func_mode_link () # These systems don't actually have a C library (as such) test X-lc = "X$arg" && continue ;; - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*) # Do not include libc due to us having libc/libc_r. test X-lc = "X$arg" && continue ;; @@ -7039,7 +7447,7 @@ func_mode_link () esac elif test X-lc_r = "X$arg"; then case $host in - *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-bitrig*) + *-*-openbsd* | *-*-freebsd* | *-*-dragonfly* | *-*-midnightbsd*) # Do not include libc_r directly, use -pthread flag. continue ;; @@ -7062,16 +7470,29 @@ func_mode_link () # Tru64 UNIX uses -model [arg] to determine the layout of C++ # classes, name mangling, and exception handling. # Darwin uses the -arch flag to determine output architecture. - -model|-arch|-isysroot|--sysroot) + # -q