Compare commits

..
Author SHA1 Message Date
Philip Homburg e5fd7dbcd1 Added gen-autotrust_addpend_2exceed (and gen-common) 2023-01-31 17:25:37 +01:00
Philip Homburg ceef1639d4 Script to generate autotrust_10key.rpl 2023-01-11 13:50:28 +01:00
W.C.A. Wijngaards 2025946247 Changelog note for tag for 1.17.1rc1.
- Tag for 1.17.1 release.
2023-01-05 11:06:07 +01:00
Alex BandandGitHub e92bd614c0 Add Mastodon link 2023-01-04 16:21:43 +01:00
Alex BandandGitHub f93fdb5e09 Add Mastodon 2023-01-04 15:57:45 +01:00
W.C.A. Wijngaards 70260273a4 - Update github workflows to use checkout v3. 2023-01-02 13:30:03 +01:00
W.C.A. Wijngaards 1224cd9d25 - Fix windows compile for libunbound subprocess reap comm point closes. 2023-01-02 13:06:39 +01:00
George Thessalonikefs 0682d4371e - Merge #569 from JINMEI Tatuya: add keep-cache option to
'unbound-control reload' to keep caches.
2022-12-14 16:40:00 +01:00
George Thessalonikefs 7716d26d46 - Use an explicit 'reload_keep_cache' command and introduce test cases
for #569.
2022-12-14 16:33:28 +01:00
George Thessalonikefs 857d6ce3a1 Merge branch 'reuse-caches-on-reload' of https://github.com/jinmeiib/unbound-1 into jinmeiib-reuse-caches-on-reload 2022-12-13 16:42:38 +01:00
George Thessalonikefs af2ef61c49 - Merge #461 from Christian Allred: Add max-query-restarts option. 2022-12-13 15:54:51 +01:00
George Thessalonikefs df411b3f28 - Updates for #461 (Add max-query-restarts option). 2022-12-13 15:29:22 +01:00
George Thessalonikefs 71db243b0d Merge branch 'restart_conf' of https://github.com/cgallred/unbound into cgallred-restart_conf 2022-12-13 14:35:01 +01:00
George Thessalonikefs 67cf625608 Merge branch 'master' of github.com:NLnetLabs/unbound 2022-12-13 13:59:42 +01:00
George Thessalonikefs c61b2121b5 - Expose 'max-sent-count' as a configuration option; the
default value retains Unbound's behavior.
2022-12-13 13:57:07 +01:00
George Thessalonikefs 859d0f2dfe - Expose 'statistics-inhibit-zero' as a configuration option; the
default value retains Unbound's behavior.
2022-12-13 10:47:37 +01:00
W.C.A. Wijngaards 1a2e6aabac - Fix to wrap Makefile scripts directory in quotes for uninstall. 2022-12-13 09:03:52 +01:00
W.C.A. Wijngaards 726aa5b0f5 Changelog note for #808
- Merge #808: Wrap Makefile script's directory variables in quotes.
2022-12-13 08:53:44 +01:00
Wouter WijngaardsandGitHub 5204c14e6d Merge pull request #808 from sneurlax/fix/windows
Wrap Makefile script's directory variables in quotes
2022-12-13 08:53:07 +01:00
sneurlax 2daaebf3aa wrap directory variables in quotes
see https://github.com/NLnetLabs/unbound/issues/807
2022-12-12 19:27:19 -06:00
W.C.A. Wijngaards 6b8642b662 Fix date. 2022-12-01 13:05:02 +01:00
W.C.A. Wijngaards 5c041c0ba9 - Fix #773: When used with systemd-networkd, unbound does not start
until systemd-networkd-wait-online.service times out.
2022-12-01 13:04:05 +01:00
George Thessalonikefs d7a9def160 - Clear documentation for interactivity between the subnet module and
the serve-expired and prefetch configuration options.
2022-11-30 14:45:36 +01:00
George Thessalonikefs ef8111ece7 Merge branch 'master' of github.com:NLnetLabs/unbound 2022-11-30 14:34:00 +01:00
George Thessalonikefs 90f6cb1158 - Add SVCB and HTTPS to the types removed by 'unbound-control flush'. 2022-11-30 14:33:16 +01:00
W.C.A. Wijngaards effbf99281 - Fix #782: Segmentation fault in stats.c:404. 2022-11-30 10:18:27 +01:00
Philip Homburg 81861aee05 Changelog entry for #720 2022-11-29 16:20:52 +01:00
W.C.A. Wijngaards 6f7da59b77 - Fix for the ignore of tcp events for closed comm points, preserve
the use after free protection features.
2022-11-28 10:04:52 +01:00
Philip-NLnetLabsandGitHub b86a97019f Merge pull request #720 from jonathangray/winsock_uaf
fix use after free when WSACreateEvent() fails
2022-11-23 14:08:01 +01:00
George Thessalonikefs 896f7a8306 - Ignore expired error responses. 2022-11-22 17:44:55 +01:00
W.C.A. Wijngaards f72116883b - Fix #779: [doc] Missing documention in ub_resolve_event() for
callback parameter was_ratelimited.
2022-11-11 11:28:15 +01:00
George Thessalonikefs 4e305e644b - Complementary fix for distutils.sysconfig deprecation in Python 3.10
to commit 62c5039ab9.
2022-11-09 11:41:28 +01:00
W.C.A. Wijngaards 89d9b25090 - iana portlist update. 2022-11-08 15:24:24 +01:00
W.C.A. Wijngaards dda1d9544c - Fix #775: libunbound: subprocess reap causes parent process reap
to hang.
2022-11-08 15:04:05 +01:00
W.C.A. Wijngaards 52a9e6268e - Fix to make sure to not read again after a tcp comm point is closed. 2022-11-08 13:23:44 +01:00
W.C.A. Wijngaards 8367b24bc5 - Fix to ignore tcp events for closed comm points. 2022-11-08 12:02:48 +01:00
JINMEI Tatuya fccb2eb2e8 prevent memory leak in case cache isn't reused 2022-07-22 14:33:21 -07:00
Jonathan Gray 1464b166a4 fix use after free when WSACreateEvent() fails 2022-07-22 18:23:59 +10:00
Christian Allred d19e12ab5d Merge branch 'master' of https://github.com/NLnetLabs/unbound into restart_conf 2022-04-18 12:16:40 -07:00
JINMEI Tatuya 5b2eda28e3 add keep-cache option to unbound-control reload to keep caches 2021-11-11 10:47:08 -08:00
Christian Allred 766244bd81 Document max-query-restarts option 2021-04-05 18:59:09 -07:00
Christian Allred 07c0d04a14 Use max-query-restarts in iterative resolver 2021-04-05 16:25:43 -07:00
Christian Allred 0e3068559c Add max-query-restarts to grammar and lexer 2021-04-05 16:24:49 -07:00
Christian Allred 41fa45c99e Add max-query-restarts config parameter 2021-04-05 15:41:53 -07:00
84 changed files with 9601 additions and 10243 deletions
+1 -1
View File
@@ -163,7 +163,7 @@ jobs:
make: "no"
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
with:
submodules: false
- name: test_windows
+1 -1
View File
@@ -12,7 +12,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v3
- name: configure
run: ./configure --enable-debug
- name: make
+5 -7
View File
@@ -128,7 +128,7 @@ util/config_file.c util/configlexer.c util/configparser.c \
util/shm_side/shm_main.c services/authzone.c \
util/fptr_wlist.c util/locks.c util/log.c util/mini_event.c util/module.c \
util/netevent.c util/net_help.c util/random.c util/rbtree.c util/regional.c \
util/rtt.c util/siphash.c util/edns.c util/storage/dnstree.c util/storage/lookup3.c \
util/rtt.c util/edns.c util/storage/dnstree.c util/storage/lookup3.c \
util/storage/lruhash.c util/storage/slabhash.c util/tcp_conn_limit.c \
util/timehist.c util/tube.c util/proxy_protocol.c \
util/ub_event.c util/ub_event_pluggable.c util/winsock_event.c \
@@ -145,7 +145,7 @@ as112.lo msgparse.lo msgreply.lo packed_rrset.lo iterator.lo iter_delegpt.lo \
iter_donotq.lo iter_fwd.lo iter_hints.lo iter_priv.lo iter_resptype.lo \
iter_scrub.lo iter_utils.lo localzone.lo mesh.lo modstack.lo view.lo \
outbound_list.lo alloc.lo config_file.lo configlexer.lo configparser.lo \
fptr_wlist.lo siphash.lo edns.lo locks.lo log.lo mini_event.lo module.lo net_help.lo \
fptr_wlist.lo edns.lo locks.lo log.lo mini_event.lo module.lo net_help.lo \
random.lo rbtree.lo regional.lo rtt.lo dnstree.lo lookup3.lo lruhash.lo \
slabhash.lo tcp_conn_limit.lo timehist.lo tube.lo winsock_event.lo \
autotrust.lo val_anchor.lo rpz.lo proxy_protocol.lo \
@@ -616,7 +616,7 @@ install-all: all $(PYTHONMOD_INSTALL) $(PYUNBOUND_INSTALL) $(UNBOUND_EVENT_INSTA
$(INSTALL) -c -m 644 doc/unbound.conf.5 $(DESTDIR)$(mandir)/man5
$(INSTALL) -c -m 644 doc/unbound-host.1 $(DESTDIR)$(mandir)/man1
$(INSTALL) -c -m 755 unbound-control-setup $(DESTDIR)$(sbindir)/unbound-control-setup
if test ! -e $(DESTDIR)$(configfile); then $(INSTALL) -d `dirname $(DESTDIR)$(configfile)`; $(INSTALL) -c -m 644 doc/example.conf $(DESTDIR)$(configfile); fi
if test ! -e "$(DESTDIR)$(configfile)"; then $(INSTALL) -d `dirname "$(DESTDIR)$(configfile)"`; $(INSTALL) -c -m 644 doc/example.conf "$(DESTDIR)$(configfile)"; fi
pythonmod-uninstall:
rm -f -- $(DESTDIR)$(PYTHON_SITE_PKG)/unboundmodule.py
@@ -645,7 +645,7 @@ uninstall: $(PYTHONMOD_UNINSTALL) $(PYUNBOUND_UNINSTALL) $(UNBOUND_EVENT_UNINSTA
rm -f -- $(DESTDIR)$(includedir)/unbound.h
$(LIBTOOL) --mode=uninstall rm -f $(DESTDIR)$(libdir)/libunbound.la
@echo
@echo "You still need to remove "`dirname $(DESTDIR)$(configfile)`" , $(DESTDIR)$(configfile) by hand"
@echo "You still need to remove "`dirname "$(DESTDIR)$(configfile)"`" , $(DESTDIR)$(configfile) by hand"
iana_update:
curl -o port-numbers.tmp https://www.iana.org/assignments/service-names-port-numbers/service-names-port-numbers.xml --compressed
@@ -915,8 +915,7 @@ config_file.lo config_file.o: $(srcdir)/util/config_file.c config.h $(srcdir)/ut
configlexer.lo configlexer.o: util/configlexer.c config.h $(srcdir)/util/configyyrename.h \
$(srcdir)/util/config_file.h util/configparser.h
configparser.lo configparser.o: util/configparser.c config.h $(srcdir)/util/configyyrename.h \
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/sldns/str2wire.h \
$(srcdir)/sldns/rrdef.h
$(srcdir)/util/config_file.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h
shm_main.lo shm_main.o: $(srcdir)/util/shm_side/shm_main.c config.h $(srcdir)/util/shm_side/shm_main.h \
$(srcdir)/libunbound/unbound.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
@@ -1007,7 +1006,6 @@ rtt.lo rtt.o: $(srcdir)/util/rtt.c config.h $(srcdir)/util/rtt.h $(srcdir)/itera
$(srcdir)/services/outbound_list.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h \
$(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/module.h \
$(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h
siphash.lo siphash.o: $(srcdir)/util/siphash.c
edns.lo edns.o: $(srcdir)/util/edns.c config.h $(srcdir)/util/edns.h $(srcdir)/util/storage/dnstree.h \
$(srcdir)/util/rbtree.h $(srcdir)/util/config_file.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
$(srcdir)/util/net_help.h $(srcdir)/util/log.h $(srcdir)/util/regional.h \
+1
View File
@@ -4,6 +4,7 @@
[![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)
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
+9 -3
View File
@@ -551,10 +551,16 @@ parse_data(struct module_qstate* qstate, struct sldns_buffer* buf)
verbose(VERB_ALGO, "cachedb msg expired");
/* If serve-expired is enabled, we still use an expired message
* setting the TTL to 0. */
if(qstate->env->cfg->serve_expired)
adjust = -1;
else
if(!qstate->env->cfg->serve_expired ||
(FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
!= LDNS_RCODE_NOERROR &&
FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
!= LDNS_RCODE_NXDOMAIN &&
FLAGS_GET_RCODE(qstate->return_msg->rep->flags)
!= LDNS_RCODE_YXDOMAIN))
return 0; /* message expired */
else
adjust = -1;
}
verbose(VERB_ALGO, "cachedb msg adjusted down by %d", (int)adjust);
adjust_msg_ttl(qstate->return_msg, adjust);
+2 -3
View File
@@ -42,9 +42,8 @@
[Unit]
Description=Validating, recursive, and caching DNS resolver
Documentation=man:unbound(8)
After=network-online.target
Before=nss-lookup.target
Wants=network-online.target nss-lookup.target
After=network.target
Before=network-online.target nss-lookup.target
[Install]
WantedBy=multi-user.target
-2
View File
@@ -109,8 +109,6 @@ parse_acl_access(const char* str, enum acl_access* control)
*control = acl_allow_snoop;
else if(strcmp(str, "allow_setrd") == 0)
*control = acl_allow_setrd;
else if (strcmp(str, "allow_cookie") == 0)
*control = acl_allow_cookie;
else {
log_err("access control type %s unknown", str);
return 0;
+1 -3
View File
@@ -65,9 +65,7 @@ enum acl_access {
/** allow full access for all queries, recursion and cache snooping */
acl_allow_snoop,
/** allow full access for recursion queries and set RD flag regardless of request */
acl_allow_setrd,
/** allow full access if valid cookie present or stateful transport */
acl_allow_cookie
acl_allow_setrd
};
/**
+5 -4
View File
@@ -387,7 +387,7 @@ move_into_cache(struct ub_packed_rrset_key* k,
struct rrset_ref ref;
uint8_t* p;
ak = alloc_special_obtain(&worker->alloc);
ak = alloc_special_obtain(worker->alloc);
if(!ak) {
log_warn("error out of memory");
return 0;
@@ -398,7 +398,7 @@ move_into_cache(struct ub_packed_rrset_key* k,
ak->rk.dname = (uint8_t*)memdup(k->rk.dname, k->rk.dname_len);
if(!ak->rk.dname) {
log_warn("error out of memory");
ub_packed_rrset_parsedelete(ak, &worker->alloc);
ub_packed_rrset_parsedelete(ak, worker->alloc);
return 0;
}
s = sizeof(*ad) + (sizeof(size_t) + sizeof(uint8_t*) +
@@ -408,7 +408,7 @@ move_into_cache(struct ub_packed_rrset_key* k,
ad = (struct packed_rrset_data*)malloc(s);
if(!ad) {
log_warn("error out of memory");
ub_packed_rrset_parsedelete(ak, &worker->alloc);
ub_packed_rrset_parsedelete(ak, worker->alloc);
return 0;
}
p = (uint8_t*)ad;
@@ -431,7 +431,8 @@ move_into_cache(struct ub_packed_rrset_key* k,
ref.key = ak;
ref.id = ak->id;
(void)rrset_cache_update(worker->env.rrset_cache, &ref,
&worker->alloc, *worker->env.now);
worker->alloc, *worker->env.now);
return 1;
}
+87 -4
View File
@@ -488,6 +488,27 @@ static int daemon_get_shufport(struct daemon* daemon, int* shufport)
return avail;
}
/**
* Clear and delete per-worker alloc caches, and free memory maintained in
* superalloc.
* The rrset and message caches must be empty at the time of call.
* @param daemon: the daemon that maintains the alloc caches to be cleared.
*/
static void
daemon_clear_allocs(struct daemon* daemon)
{
int i;
for(i=0; i<daemon->num; i++) {
alloc_clear(daemon->worker_allocs[i]);
free(daemon->worker_allocs[i]);
}
free(daemon->worker_allocs);
daemon->worker_allocs = NULL;
alloc_clear_special(&daemon->superalloc);
}
/**
* Allocate empty worker structures. With backptr and thread-number,
* from 0..numthread initialised. Used as user arguments to new threads.
@@ -540,6 +561,21 @@ daemon_create_workers(struct daemon* daemon)
/* the above is not ports/numthr, due to rounding */
fatal_exit("could not create worker");
}
/* create per-worker alloc caches if not reusing existing ones. */
if(!daemon->worker_allocs) {
daemon->worker_allocs = (struct alloc_cache**)calloc(
(size_t)daemon->num, sizeof(struct alloc_cache*));
if(!daemon->worker_allocs)
fatal_exit("could not allocate worker allocs");
for(i=0; i<daemon->num; i++) {
struct alloc_cache* alloc = calloc(1,
sizeof(struct alloc_cache));
if (!alloc)
fatal_exit("could not allocate worker alloc");
alloc_init(alloc, &daemon->superalloc, i);
daemon->worker_allocs[i] = alloc;
}
}
free(shufport);
}
@@ -771,6 +807,7 @@ daemon_fork(struct daemon* daemon)
/* Shutdown SHM */
shm_main_shutdown(daemon);
daemon->reuse_cache = daemon->workers[0]->reuse_cache;
daemon->need_to_exit = daemon->workers[0]->need_to_exit;
}
@@ -785,9 +822,16 @@ daemon_cleanup(struct daemon* daemon)
log_thread_set(NULL);
/* clean up caches because
* a) RRset IDs will be recycled after a reload, causing collisions
* b) validation config can change, thus rrset, msg, keycache clear */
slabhash_clear(&daemon->env->rrset_cache->table);
slabhash_clear(daemon->env->msg_cache);
* b) validation config can change, thus rrset, msg, keycache clear
*
* If we are trying to keep the cache as long as possible, we should
* defer the cleanup until we know whether the new configuration allows
* the reuse. (If we're exiting, cleanup should be done here). */
if(!daemon->reuse_cache || daemon->need_to_exit) {
slabhash_clear(&daemon->env->rrset_cache->table);
slabhash_clear(daemon->env->msg_cache);
}
daemon->old_num = daemon->num; /* save the current num */
local_zones_delete(daemon->local_zones);
daemon->local_zones = NULL;
respip_set_delete(daemon->respip_set);
@@ -802,8 +846,13 @@ daemon_cleanup(struct daemon* daemon)
worker_delete(daemon->workers[i]);
free(daemon->workers);
daemon->workers = NULL;
/* Unless we're trying to keep the cache, worker alloc_caches should be
* cleared and freed here. We do this after deleting workers to
* guarantee that the alloc caches are valid throughout the lifetime
* of workers. */
if(!daemon->reuse_cache || daemon->need_to_exit)
daemon_clear_allocs(daemon);
daemon->num = 0;
alloc_clear_special(&daemon->superalloc);
#ifdef USE_DNSTAP
dt_delete(daemon->dtenv);
daemon->dtenv = NULL;
@@ -900,8 +949,42 @@ daemon_delete(struct daemon* daemon)
void daemon_apply_cfg(struct daemon* daemon, struct config_file* cfg)
{
int new_num = cfg->num_threads?cfg->num_threads:1;
daemon->cfg = cfg;
config_apply(cfg);
/* If this is a reload and we deferred the decision on whether to
* reuse the alloc, RRset, and message caches, then check to see if
* it's safe to keep the caches:
* - changing the number of threads is obviously incompatible with
* keeping the per-thread alloc caches. It also means we have to
* clear RRset and message caches. (note that 'new_num' may be
* adjusted in daemon_create_workers, but for our purpose we can
* simply compare it with 'old_num'; if they are equal here,
* 'new_num' won't be adjusted to a different value than 'old_num').
* - changing RRset cache size effectively clears any remaining cache
* entries. We could keep their keys in alloc caches, but it would
* be more consistent with the sense of the change to clear allocs
* and free memory. To do so we also have to clear message cache.
* - only changing message cache size does not necessarily affect
* RRset or alloc cache. But almost all new subsequent queries will
* require recursive resolution anyway, so it doesn't help much to
* just keep RRset and alloc caches. For simplicity we clear/free
* the other two, too. */
if(daemon->worker_allocs &&
(new_num != daemon->old_num ||
!slabhash_is_size(daemon->env->msg_cache, cfg->msg_cache_size,
cfg->msg_cache_slabs) ||
!slabhash_is_size(&daemon->env->rrset_cache->table,
cfg->rrset_cache_size, cfg->rrset_cache_slabs)))
{
log_warn("cannot reuse caches due to critical config change");
slabhash_clear(&daemon->env->rrset_cache->table);
slabhash_clear(daemon->env->msg_cache);
daemon_clear_allocs(daemon);
}
if(!slabhash_is_size(daemon->env->msg_cache, cfg->msg_cache_size,
cfg->msg_cache_slabs)) {
slabhash_delete(daemon->env->msg_cache);
+6
View File
@@ -99,8 +99,12 @@ struct daemon {
void* listen_sslctx, *connect_sslctx;
/** num threads allocated */
int num;
/** num threads allocated in the previous config or 0 at first */
int old_num;
/** the worker entries */
struct worker** workers;
/** per-worker allocation cache */
struct alloc_cache **worker_allocs;
/** do we need to exit unbound (or is it only a reload?) */
int need_to_exit;
/** master random table ; used for port div between threads on reload*/
@@ -140,6 +144,8 @@ struct daemon {
/** the dnscrypt environment */
struct dnsc_env* dnscenv;
#endif
/** reuse existing cache on reload if other conditions allow it. */
int reuse_cache;
};
/**
+10 -6
View File
@@ -105,8 +105,6 @@
/** what to put on statistics lines between var and value, ": " or "=" */
#define SQ "="
/** if true, inhibits a lot of =0 lines from the stats output */
static const int inhibit_zero = 1;
/** subtract timers and the values do not overflow or become negative */
static void
@@ -684,8 +682,9 @@ do_stop(RES* ssl, struct worker* worker)
/** do the reload command */
static void
do_reload(RES* ssl, struct worker* worker)
do_reload(RES* ssl, struct worker* worker, int reuse_cache)
{
worker->reuse_cache = reuse_cache;
worker->need_to_exit = 0;
comm_base_exit(worker->base);
send_ok(ssl);
@@ -920,7 +919,7 @@ print_hist(RES* ssl, struct ub_stats_info* s)
/** print extended stats */
static int
print_ext(RES* ssl, struct ub_stats_info* s)
print_ext(RES* ssl, struct ub_stats_info* s, int inhibit_zero)
{
int i;
char nm[32];
@@ -1129,7 +1128,7 @@ do_stats(RES* ssl, struct worker* worker, int reset)
return;
if(!print_hist(ssl, &total))
return;
if(!print_ext(ssl, &total))
if(!print_ext(ssl, &total, daemon->cfg->stat_inhibit_zero))
return;
}
}
@@ -1963,6 +1962,8 @@ do_flush_name(RES* ssl, struct worker* w, char* arg)
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_PTR, LDNS_RR_CLASS_IN);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_SRV, LDNS_RR_CLASS_IN);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_NAPTR, LDNS_RR_CLASS_IN);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_SVCB, LDNS_RR_CLASS_IN);
do_cache_remove(w, nm, nmlen, LDNS_RR_TYPE_HTTPS, LDNS_RR_CLASS_IN);
free(nm);
send_ok(ssl);
@@ -3029,8 +3030,11 @@ execute_cmd(struct daemon_remote* rc, RES* ssl, char* cmd,
if(cmdcmp(p, "stop", 4)) {
do_stop(ssl, worker);
return;
} else if(cmdcmp(p, "reload_keep_cache", 17)) {
do_reload(ssl, worker, 1);
return;
} else if(cmdcmp(p, "reload", 6)) {
do_reload(ssl, worker);
do_reload(ssl, worker, 0);
return;
} else if(cmdcmp(p, "stats_noreset", 13)) {
do_stats(ssl, worker, 0);
+29 -54
View File
@@ -133,7 +133,7 @@ worker_mem_report(struct worker* ATTR_UNUSED(worker),
rrset = slabhash_get_mem(&worker->env.rrset_cache->table);
infra = infra_get_mem(worker->env.infra_cache);
mesh = mesh_get_mem(worker->env.mesh);
ac = alloc_get_mem(&worker->alloc);
ac = alloc_get_mem(worker->alloc);
superac = alloc_get_mem(&worker->daemon->superalloc);
anch = anchors_get_mem(worker->env.anchors);
iter = 0;
@@ -623,6 +623,14 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
if(worker->env.cfg->serve_expired_ttl &&
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 &&
FLAGS_GET_RCODE(rep->flags) !=
LDNS_RCODE_YXDOMAIN)
return 0;
if(!rrset_array_lock(rep->ref, rep->rrset_count, 0))
return 0;
*is_expired_answer = 1;
@@ -730,8 +738,6 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
goto bail_out;
}
} else {
/* We don't check the global ede as this is a warning, not
* an error */
if (*is_expired_answer == 1 &&
worker->env.cfg->ede_serve_expired && worker->env.cfg->ede) {
EDNS_OPT_LIST_APPEND_EDE(&edns->opt_list_out,
@@ -1455,16 +1461,16 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
}
goto send_reply;
}
if((ret=parse_edns_from_query_pkt(
c->buffer, &edns, worker->env.cfg, c, repinfo,
(worker->env.now ? *worker->env.now : time(NULL)),
worker->scratchpad)) != 0) {
if((ret=parse_edns_from_query_pkt(c->buffer, &edns, worker->env.cfg, c,
worker->scratchpad)) != 0) {
struct edns_data reply_edns;
verbose(VERB_ALGO, "worker parse edns: formerror.");
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
repinfo->client_addrlen);
memset(&reply_edns, 0, sizeof(reply_edns));
reply_edns.edns_present = 1;
reply_edns.udp_size = EDNS_ADVERTISED_SIZE;
LDNS_RCODE_SET(sldns_buffer_begin(c->buffer), ret);
error_encode(c->buffer, ret, &qinfo,
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2), &reply_edns);
@@ -1473,15 +1479,23 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
}
if(edns.edns_present) {
if(edns.edns_version != 0) {
edns.ext_rcode = (uint8_t)(EDNS_RCODE_BADVERS>>4);
edns.edns_version = EDNS_ADVERTISED_VERSION;
edns.udp_size = EDNS_ADVERTISED_SIZE;
edns.bits &= EDNS_DO;
edns.opt_list_in = NULL;
edns.opt_list_out = NULL;
edns.opt_list_inplace_cb_out = NULL;
edns.padding_block_size = 0;
verbose(VERB_ALGO, "query with bad edns version.");
log_addr( VERB_CLIENT, "from",&repinfo->remote_addr
, repinfo->remote_addrlen);
extended_error_encode(c->buffer, EDNS_RCODE_BADVERS, &qinfo,
log_addr(VERB_CLIENT, "from", &repinfo->client_addr,
repinfo->client_addrlen);
error_encode(c->buffer, EDNS_RCODE_BADVERS&0xf, &qinfo,
*(uint16_t*)(void *)sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2), 0, &edns);
sldns_buffer_read_u16_at(c->buffer, 2), NULL);
if(sldns_buffer_capacity(c->buffer) >=
sldns_buffer_limit(c->buffer)+calc_edns_field_size(&edns))
attach_edns_record(c->buffer, &edns);
regional_free_all(worker->scratchpad);
goto send_reply;
}
@@ -1494,44 +1508,6 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
edns.udp_size = NORMAL_UDP_SIZE;
}
}
/* "if, else if" sequence below deals with downstream DNS Cookies */
if (acl != acl_allow_cookie)
; /* pass; No cookie downstream processing whatsoever */
else if (edns.cookie_valid)
; /* pass; Valid cookie is good! */
else if (c->type != comm_udp)
; /* pass; Stateful transport */
else if (edns.cookie_present) {
/* Cookie present, but not valid: Cookie was bad! */
extended_error_encode(c->buffer,
LDNS_EXT_RCODE_BADCOOKIE, &qinfo,
*(uint16_t*)(void *)
sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2),
0, &edns);
regional_free_all(worker->scratchpad);
goto send_reply;
} else {
/* Cookie requered, but no cookie present on UDP */
verbose(VERB_ALGO, "worker request: "
"need cookie or stateful transport");
log_addr(VERB_ALGO, "from",&repinfo->remote_addr
, repinfo->remote_addrlen);
EDNS_OPT_LIST_APPEND_EDE(&edns.opt_list_out,
worker->scratchpad, LDNS_EDE_OTHER,
"DNS Cookie needed for UDP replies");
error_encode(c->buffer,
(LDNS_RCODE_REFUSED|BIT_TC), &qinfo,
*(uint16_t*)(void *)
sldns_buffer_begin(c->buffer),
sldns_buffer_read_u16_at(c->buffer, 2),
&edns);
regional_free_all(worker->scratchpad);
goto send_reply;
}
if(edns.udp_size > worker->daemon->cfg->max_udp_size &&
c->type == comm_udp) {
verbose(VERB_QUERY,
@@ -2089,15 +2065,14 @@ worker_init(struct worker* worker, struct config_file *cfg,
}
server_stats_init(&worker->stats, cfg);
alloc_init(&worker->alloc, &worker->daemon->superalloc,
worker->thread_num);
alloc_set_id_cleanup(&worker->alloc, &worker_alloc_cleanup, worker);
worker->alloc = worker->daemon->worker_allocs[worker->thread_num];
alloc_set_id_cleanup(worker->alloc, &worker_alloc_cleanup, worker);
worker->env = *worker->daemon->env;
comm_base_timept(worker->base, &worker->env.now, &worker->env.now_tv);
worker->env.worker = worker;
worker->env.worker_base = worker->base;
worker->env.send_query = &worker_send_query;
worker->env.alloc = &worker->alloc;
worker->env.alloc = worker->alloc;
worker->env.outnet = worker->back;
worker->env.rnd = worker->rndstate;
/* If case prefetch is triggered, the corresponding mesh will clear
@@ -2241,7 +2216,7 @@ worker_delete(struct worker* worker)
#endif /* USE_DNSTAP */
comm_base_delete(worker->base);
ub_randfree(worker->rndstate);
alloc_clear(&worker->alloc);
/* don't touch worker->alloc, as it's maintained in daemon */
regional_destroy(worker->env.scratch);
regional_destroy(worker->scratchpad);
free(worker);
+3 -1
View File
@@ -118,7 +118,7 @@ struct worker {
/** do we need to restart or quit (on signal) */
int need_to_exit;
/** allocation cache for this thread */
struct alloc_cache alloc;
struct alloc_cache *alloc;
/** per thread statistics */
struct ub_server_stats stats;
/** thread scratch regional */
@@ -131,6 +131,8 @@ struct worker {
/** dnstap environment, changed for this thread */
struct dt_env dtenv;
#endif
/** reuse existing cache on reload if other conditions allow it. */
int reuse_cache;
};
/**
+62
View File
@@ -1,3 +1,65 @@
5 January 2023: Wouter
- Tag for 1.17.1 release.
2 January 2023: Wouter
- Fix windows compile for libunbound subprocess reap comm point closes.
- Update github workflows to use checkout v3.
14 December 2022: George
- Merge #569 from JINMEI Tatuya: add keep-cache option to
'unbound-control reload' to keep caches.
13 December 2022: George
- Expose 'statistics-inhibit-zero' as a configuration option; the
default value retains Unbound's behavior.
- Expose 'max-sent-count' as a configuration option; the
default value retains Unbound's behavior.
- Merge #461 from Christian Allred: Add max-query-restarts option.
Exposes an internal configuration but the default value retains
Unbound's behavior.
13 December 2022: Wouter
- Merge #808: Wrap Makefile script's directory variables in quotes.
- Fix to wrap Makefile scripts directory in quotes for uninstall.
1 December 2022: Wouter
- Fix #773: When used with systemd-networkd, unbound does not start
until systemd-networkd-wait-online.service times out.
30 November 2022: George
- Add SVCB and HTTPS to the types removed by 'unbound-control flush'.
- Clear documentation for interactivity between the subnet module and
the serve-expired and prefetch configuration options.
30 November 2022: Wouter
- Fix #782: Segmentation fault in stats.c:404.
28 November 2022: Wouter
- Fix for the ignore of tcp events for closed comm points, preserve
the use after free protection features.
23 November 2022: Philip
- Merge #720 from jonathangray: fix use after free when
WSACreateEvent() fails.
22 November 2022: George
- Ignore expired error responses.
11 November 2022: Wouter
- Fix #779: [doc] Missing documention in ub_resolve_event() for
callback parameter was_ratelimited.
9 November 2022: George
- Complementary fix for distutils.sysconfig deprecation in Python 3.10
to commit 62c5039ab9da42713e006e840b7578e01d66e7f2.
8 November 2022: Wouter
- Fix to ignore tcp events for closed comm points.
- Fix to make sure to not read again after a tcp comm point is closed.
- Fix #775: libunbound: subprocess reap causes parent process reap
to hang.
- iana portlist update.
21 October 2022: George
- Merge #767 from jonathangray: consistently use IPv4/IPv6 in
unbound.conf.5.
+15 -1
View File
@@ -35,9 +35,14 @@ server:
# statistics-cumulative: no
# enable extended statistics (query types, answer codes, status)
# printed from unbound-control. default off, because of speed.
# printed from unbound-control. Default off, because of speed.
# extended-statistics: no
# Inhibits selected extended statistics (qtype, qclass, qopcode, rcode,
# rpz-actions) from printing if their value is 0.
# Default on.
# statistics-inhibit-zero: yes
# number of threads to create. 1 disables threading.
# num-threads: 1
@@ -173,6 +178,15 @@ server:
# a throwaway response (also timeouts) is received.
# outbound-msg-retry: 5
# Hard limit on the number of outgoing queries Unbound will make while
# resolving a name, making sure large NS sets do not loop.
# It resets on query restarts (e.g., CNAME) and referrals.
# max-sent-count: 32
# Hard limit on the number of times Unbound is allowed to restart a
# query upon encountering a CNAME record.
# max-query-restarts: 11
# msec for waiting for an unknown server to reply. Increase if you
# are behind a slow satellite link, to eg. 1128.
# unknown-server-time-limit: 376
+7 -1
View File
@@ -54,6 +54,12 @@ Stop the server. The server daemon exits.
.B reload
Reload the server. This flushes the cache and reads the config file fresh.
.TP
.B reload_keep_cache
Reload the server but try to keep the RRset and message cache if
(re)configuration allows for it.
That means the caches sizes and the number of threads must not change between
reloads.
.TP
.B verbosity \fInumber
Change verbosity value for logging. Same values as \fBverbosity\fR keyword in
\fIunbound.conf\fR(5). This new setting lasts until the server is issued
@@ -130,7 +136,7 @@ name specified.
.TP
.B flush \fIname
Remove the name from the cache. Removes the types
A, AAAA, NS, SOA, CNAME, DNAME, MX, PTR, SRV and NAPTR.
A, AAAA, NS, SOA, CNAME, DNAME, MX, PTR, SRV, NAPTR, SVCB and HTTPS.
Because that is fast to do. Other record types can be removed using
.B flush_type
or
+30 -30
View File
@@ -112,6 +112,14 @@ If enabled, extended statistics are printed from \fIunbound\-control\fR(8).
Default is off, because keeping track of more statistics takes time. The
counters are listed in \fIunbound\-control\fR(8).
.TP
.B statistics\-inhibit\-zero: \fI<yes or no>
If enabled, selected extended statistics with a value of 0 are inhibited from
printing with \fIunbound\-control\fR(8).
These are query types, query classes, query opcodes, answer rcodes
(except NOERROR, FORMERR, SERVFAIL, NXDOMAIN, NOTIMPL, REFUSED) and
RPZ actions.
Default is on.
.TP
.B num\-threads: \fI<number>
The number of threads to create to serve clients. Use 1 for no threading.
.TP
@@ -507,15 +515,6 @@ Enable udp upstream even if do-udp is no. Default is no, and this does not
change anything. Useful for TLS service providers, that want no udp downstream
but use udp to fetch data upstream.
.TP
.B upstream-cookies: \fI<yes or no>
Enable EDNS cookies from upstream connections. DNS Cookies, as specified in
RFC 7873 and 9018 provide a limited-protection transaction security mechanism.
Once a cookie has been exchanged, the resolver and upstream are known to each
other and requests to the upstream can be exempted from rate limiting, for
example. Note that RFC9018 specifies that cookies should not be reused for
multiple outgoing interfaces, which is not supported at this time. The default
is no.
.TP
.B tls\-upstream: \fI<yes or no>
Enabled or disable whether the upstream queries use TLS only for transport.
Default is no. Useful in tunneling scenarios. The TLS contains plain DNS in
@@ -693,9 +692,9 @@ This option is experimental at this time.
.B access\-control: \fI<IP netblock> <action>
The netblock is given as an IP4 or IP6 address with /size appended for a
classless network block. The action can be \fIdeny\fR, \fIrefuse\fR,
\fIallow\fR, \fIallow_setrd\fR, \fIallow_snoop\fR, \fIallow_cookie\fR,
\fIdeny_non_local\fR or \fIrefuse_non_local\fR.
The most specific netblock match is used, if none match \fIdeny\fR is used.
\fIallow\fR, \fIallow_setrd\fR, \fIallow_snoop\fR, \fIdeny_non_local\fR or
\fIrefuse_non_local\fR.
The most specific netblock match is used, if none match \fIrefuse\fR is used.
The order of the access\-control statements therefore does not matter.
.IP
The action \fIdeny\fR stops queries from hosts from that netblock.
@@ -730,14 +729,6 @@ the cache contents (for malicious acts). However, nonrecursive queries can
also be a valuable debugging tool (when you want to examine the cache
contents). In that case use \fIallow_snoop\fR for your administration host.
.IP
When the \fBanswer\-cookie\fR option is enabled, the \fIallow_cookie\fR action
will allow access to UDP queries that contain a valid Server Cookie as
specified in RFC 7873 and RFC9018. UDP queries containing only a Client Cookie
and no Server Cookie, will receive a BADCOOKIE response including a Server
Cookie, allow clients to retry with that Server Cookie. The \fIallow_cookie\fR
will also accept requests over statefull transports, regardless of the precence
of a Cookie and regardless the \fBanswer\-cookie\fR setting.
.IP
By default only localhost is \fIallow\fRed, the rest is \fIrefuse\fRd.
The default is \fIrefuse\fRd, because that is protocol\-friendly. The DNS
protocol is not designed to handle dropped packets due to policy, and
@@ -1837,6 +1828,21 @@ If a forward/stub zone is used, this is the number of retries per nameserver in
the zone.
Default is 5.
.TP 5
.B max\-sent\-count: \fI<number>
Hard limit on the number of outgoing queries Unbound will make while resolving
a name, making sure large NS sets do not loop.
Results in SERVFAIL when reached.
It resets on query restarts (e.g., CNAME) and referrals.
Default is 32.
.TP 5
.B max\-query\-restarts: \fI<number>
Hard limit on the number of times Unbound is allowed to restart a query upon
encountering a CNAME record.
Results in SERVFAIL when reached.
Changing this value needs caution as it can allow long CNAME chains to be
accepted, where Unbound needs to verify (resolve) each link individually.
Default is 11.
.TP 5
.B fast\-server\-permil: \fI<number>
Specify how many times out of 1000 to pick from the set of fastest servers.
0 turns the feature off. A value of 900 would pick from the fastest
@@ -1852,15 +1858,6 @@ Set the number of servers that should be used for fast server selection. Only
use the fastest specified number of servers with the fast\-server\-permil
option, that turns this on or off. The default is to use the fastest 3 servers.
.TP 5
.B answer\-cookie: \fI<yes or no>
Enable to answer to requests containig DNS Cookies as specified in RFC7873 and
RFC9018. Default is no.
.TP 5
.B cookie\-secret: \fI<128 bit hex string>
Server's in an Anycast deployment need to be able to verify each other's
Server Cookies. For this they need to share the secret used to construct
and verify the Server Cookies.
Default is a 128 bits random secret generated at startup time.
.B edns\-client\-string: \fI<IP netblock> <string>
Include an EDNS0 option containing configured ascii string in queries with
destination address matching the configured IP netblock. This configuration
@@ -1879,7 +1876,7 @@ errors. Default is "no".
When the \fBval-log-level\fR option is also set to \fB2\fR, responses with
Extended DNS Errors concerning DNSSEC failures that are not served from cache,
will also contain a descriptive text message about the reason for the failure.
.TP
.TP 5
.B ede\-serve\-expired: \fI<yes or no>
If enabled, Unbound will attach an Extended DNS Error (RFC8914) Code 3 - Stale
Answer as EDNS0 option to the expired response. Note that this will not attach
@@ -2384,6 +2381,9 @@ The maximum size of the ECS cache is controlled by 'msg-cache-size' in the
configuration file. On top of that, for each query only 100 different subnets
are allowed to be stored for each address family. Exceeding that number, older
entries will be purged from cache.
.LP
This module does not interact with the \fBserve\-expired*\fR and
\fBprefetch:\fR options.
.TP
.B send\-client\-subnet: \fI<IP address>\fR
Send client source address to this authority. Append /num to indicate a
+11
View File
@@ -204,6 +204,17 @@ subnetmod_init(struct module_env *env, int id)
}
alloc_init(&sn_env->alloc, NULL, 0);
env->modinfo[id] = (void*)sn_env;
/* Warn that serve-expired and prefetch do not work with the subnet
* module cache. */
if(env->cfg->serve_expired)
log_warn(
"subnetcache: serve-expired is set but not working "
"for data originating from the subnet module cache.");
if(env->cfg->prefetch)
log_warn(
"subnetcache: prefetch is set but not working "
"for data originating from the subnet module cache.");
/* Copy msg_cache settings */
sn_env->subnet_msg_cache = slabhash_create(env->cfg->msg_cache_slabs,
HASH_DEFAULT_STARTARRAY, env->cfg->msg_cache_size,
+2
View File
@@ -175,6 +175,8 @@ iter_apply_cfg(struct iter_env* iter_env, struct config_file* cfg)
iter_env->supports_ipv6 = cfg->do_ip6;
iter_env->supports_ipv4 = cfg->do_ip4;
iter_env->outbound_msg_retry = cfg->outbound_msg_retry;
iter_env->max_sent_count = cfg->max_sent_count;
iter_env->max_query_restarts = cfg->max_query_restarts;
return 1;
}
+6 -157
View File
@@ -68,7 +68,6 @@
#include "sldns/str2wire.h"
#include "sldns/parseutil.h"
#include "sldns/sbuffer.h"
#include "daemon/worker.h"
/* in msec */
int UNKNOWN_SERVER_NICENESS = 376;
@@ -1315,7 +1314,7 @@ processInitRequest(struct module_qstate* qstate, struct iter_qstate* iq,
/* We enforce a maximum number of query restarts. This is primarily a
* cheap way to prevent CNAME loops. */
if(iq->query_restart_count > MAX_RESTART_COUNT) {
if(iq->query_restart_count > ie->max_query_restarts) {
verbose(VERB_QUERY, "request has exceeded the maximum number"
" of query restarts with %d", iq->query_restart_count);
errinf(qstate, "request has exceeded the maximum number "
@@ -2283,7 +2282,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
errinf(qstate, "exceeded the maximum of referrals");
return error_response(qstate, id, LDNS_RCODE_SERVFAIL);
}
if(iq->sent_count > MAX_SENT_COUNT) {
if(iq->sent_count > ie->max_sent_count) {
verbose(VERB_QUERY, "request has exceeded the maximum "
"number of sends with %d", iq->sent_count);
errinf(qstate, "exceeded the maximum number of sends");
@@ -2630,7 +2629,7 @@ processQueryTargets(struct module_qstate* qstate, struct iter_qstate* iq,
* the original query is one that matched too, so we have
* caps_server+1 number of matching queries now */
if(iq->caps_server+1 >= naddr*3 ||
iq->caps_server*2+2 >= MAX_SENT_COUNT) {
iq->caps_server*2+2 >= (size_t)ie->max_sent_count) {
/* *2 on sentcount check because ipv6 may fail */
/* we're done, process the response */
verbose(VERB_ALGO, "0x20 fallback had %d responses "
@@ -3945,79 +3944,6 @@ process_request(struct module_qstate* qstate, struct iter_qstate* iq,
iter_handle(qstate, iq, ie, id);
}
/** find the bound addr in the list of interfaces */
static int
get_bound_ip_if(struct outside_network* outnet,
struct sockaddr_storage *bound_addr, socklen_t bound_addrlen,
struct port_if* pif_return)
{
int i = 0;
struct port_if* pif_list;
int pif_list_len;
/* Get the list of interfaces and check that that list isn't just the
* "any" address */
if(addr_is_ip6(bound_addr, bound_addrlen)) {
pif_list = outnet->ip6_ifs;
pif_list_len = outnet->num_ip6;
// @TODO fix IPv6
} else {
pif_list = outnet->ip4_ifs;
pif_list_len = outnet->num_ip4;
struct sockaddr_storage addr_any;
socklen_t addr_any_len = 0;
struct sockaddr_storage addr_new;
socklen_t addr_new_len = 0;
if (!ipstrtoaddr("0.0.0.0", 0, &addr_any, &addr_any_len)) {
/* this shouldn't fail */
return 0;
}
log_addr(VERB_DETAIL, "!!!!! outnet->ip4_ifs->addr", &outnet->ip4_ifs->addr, bound_addrlen);
log_addr(VERB_DETAIL, "!!!!! addr_any", &addr_any, addr_any_len);
/* if we let the kernel decide the IP, fill in
* the previously used */
if (pif_list_len == 1 &&
sockaddr_cmp_addr(&outnet->ip4_ifs->addr, outnet->ip4_ifs->addrlen,
&addr_any, addr_any_len) == 0) {
/* return the interface from the list, but substitute the
* previously used address */
memcpy(pif_return, outnet->ip4_ifs, sizeof(struct port_if));
memcpy(&pif_return->addr, &addr_new, addr_new_len);
pif_return->addrlen = addr_new_len;
log_addr(VERB_DETAIL, "!!!!! get_bound_ip_if: addr from"
" ip4_ifs == 0.0.0.0, new is:", &pif_return->addr, outnet->ip4_ifs->addrlen);
return 1;
}
}
if (pif_list_len == 0) {
return 0;
}
for (i = 0; i < pif_list_len; i++) {
struct port_if *iface = &pif_list[i];
if (iface->addrlen == bound_addrlen &&
memcmp(&iface->addr, bound_addr, bound_addrlen)) {
memcpy(pif_return, iface, sizeof(struct port_if));
return 1;
}
}
return 0;
}
/** process authoritative server reply */
static void
process_response(struct module_qstate* qstate, struct iter_qstate* iq,
@@ -4026,34 +3952,11 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
{
struct msg_parse* prs;
struct edns_data edns;
struct edns_option* cookie;
sldns_buffer* pkt;
verbose(VERB_ALGO, "process_response: new external response event");
iq->response = NULL;
iq->state = QUERY_RESP_STATE;
if (event == module_event_interface_not_available) {
log_err("!!!!! process_response:event == module_event_interface_not_available");
}
if (!qstate->reply) {
log_err("!!!!! !qstate->reply");
}
// @TODO set renewed cookie here with infra_set_server_cookie, then bail out
if(qstate->env->cfg->upstream_cookies && event == module_event_interface_not_available) {
struct edns_cookie cookie;
// @TODO make into renew cookie function
infra_get_cookie(qstate->env->infra_cache, &qstate->reply->remote_addr,
qstate->reply->remote_addrlen, iq->dp->name, iq->dp->namelen,
*qstate->env->now, &cookie, 1);
log_err("!!!!!! interface unavailbale, renewing cookie");
goto handle_it;
}
if(event == module_event_noreply || event == module_event_error) {
if(event == module_event_noreply && iq->timeout_count >= 3 &&
qstate->env->cfg->use_caps_bits_for_id &&
@@ -4074,8 +3977,8 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
}
goto handle_it;
}
if( (event != module_event_reply && event != module_event_capsfail
&& event != module_event_interface_not_available) || !qstate->reply) {
if( (event != module_event_reply && event != module_event_capsfail)
|| !qstate->reply) {
log_err("Bad event combined with response");
outbound_list_remove(&iq->outlist, outbound);
errinf(qstate, "module iterator received wrong internal event with a response message");
@@ -4108,61 +4011,7 @@ process_response(struct module_qstate* qstate, struct iter_qstate* iq,
goto handle_it;
}
/* handle the upstream response cookie if enabled */
if(qstate->env->cfg->upstream_cookies) {
if (edns.opt_list_in &&
(cookie = edns_list_get_option(edns.opt_list_in,
LDNS_EDNS_COOKIE))){
struct sockaddr_storage bound_addr;
socklen_t bound_addrlen = sizeof(struct sockaddr);
struct port_if pif;
struct port_if *pif_ptr = &pif;
/* Get the outgoing interface to store with the cookie */
if(event != module_event_interface_not_available &&
getsockname(qstate->reply->c->fd,
(struct sockaddr *) &bound_addr,
&bound_addrlen) != -1) {
log_addr(VERB_DETAIL, "!!!!! iterator:udp socket:", &bound_addr, bound_addrlen);
if (!(get_bound_ip_if(qstate->env->worker->back,
&bound_addr, bound_addrlen, pif_ptr))) {
pif.addrlen = 0;
}
log_addr(VERB_DETAIL, "!!!!! iterator:pif addr:", &pif.addr, pif.addrlen);
} else {
/* Set to zero so the cookie gets renewed */
pif.addrlen = 0;
}
/* verify this is a 'complete cookie' (client+server)
* (RFC9018) with the length and store the complete
* cookie in the infra_cache. Do nothing when the cookie
* is already known and update when the server cookie
* changed */
if (cookie->opt_len == 24 &&
infra_set_server_cookie(qstate->env->infra_cache,
&qstate->reply->remote_addr,
qstate->reply->remote_addrlen,
iq->dp->name, iq->dp->namelen, pif_ptr,
cookie) >= 0) {
// @TODO do something
} else {
log_info("upstream response server cookie is not "
"added to cache; dropping response");
goto handle_it;
}
} else {
//@TODO think about what we do if we did send a cookie
// but did not get one back? for now we log_err()
log_err("upstream has not responded with a cookie");
}
}
/* Copy the edns options we may have gotten from the back end */
/* Copy the edns options we may got from the back end */
if(edns.opt_list_in) {
qstate->edns_opts_back_in = edns_opt_copy_region(edns.opt_list_in,
qstate->region);
+6 -5
View File
@@ -63,13 +63,8 @@ struct rbtree_type;
/** max number of nxdomains allowed for target lookups for a query and
* its subqueries when fallback has kicked in */
#define MAX_TARGET_NX_FALLBACK (MAX_TARGET_NX*2)
/** max number of query restarts. Determines max number of CNAME chain. */
#define MAX_RESTART_COUNT 11
/** max number of referrals. Makes sure resolver does not run away */
#define MAX_REFERRAL_COUNT 130
/** max number of queries-sent-out. Make sure large NS set does not loop.
* Resets on query restarts (e.g., CNAMES) and referrals. */
#define MAX_SENT_COUNT 32
/** max number of queries for which to perform dnsseclameness detection,
* (rrsigs missing detection) after that, just pick up that response */
#define DNSSEC_LAME_DETECT_COUNT 4
@@ -146,6 +141,12 @@ struct iter_env {
/** number of retries on outgoing queries */
int outbound_msg_retry;
/** number of queries_sent */
int max_sent_count;
/** max number of query restarts to limit length of CNAME chain */
int max_query_restarts;
};
/**
+1
View File
@@ -70,6 +70,7 @@ context_finalize(struct ub_ctx* ctx)
} else {
log_init(cfg->logfile, cfg->use_syslog, NULL);
}
ctx->pipe_pid = getpid();
cfg_apply_local_port_policy(cfg, 65536);
config_apply(cfg);
if(!modstack_setup(&ctx->mods, cfg->module_conf, ctx->env))
+6
View File
@@ -89,6 +89,12 @@ struct ub_ctx {
pid_t bg_pid;
/** tid of bg worker thread */
ub_thread_type bg_tid;
/** pid when pipes are created. This was the process when the
* setup was called. Helps with clean up, so we can tell after a fork
* which side of the fork the delete is on. */
pid_t pipe_pid;
/** when threaded, the worker that exists in the created thread. */
struct libworker* thread_worker;
/** do threading (instead of forking) for async resolution */
int dothread;
+38 -1
View File
@@ -305,11 +305,31 @@ ub_ctx_delete(struct ub_ctx* ctx)
int do_stop = 1;
if(!ctx) return;
/* if the delete is called but it has forked, and before the fork
* the context was finalized, then the bg worker is not stopped
* from here. There is one worker, but two contexts that refer to
* it and only one should clean up, the one with getpid == pipe_pid.*/
if(ctx->created_bg && ctx->pipe_pid != getpid()) {
do_stop = 0;
#ifndef USE_WINSOCK
/* Stop events from getting deregistered, if the backend is
* epoll, the epoll fd is the same as the other process.
* That process should deregister them. */
if(ctx->qq_pipe->listen_com)
ctx->qq_pipe->listen_com->event_added = 0;
if(ctx->qq_pipe->res_com)
ctx->qq_pipe->res_com->event_added = 0;
if(ctx->rr_pipe->listen_com)
ctx->rr_pipe->listen_com->event_added = 0;
if(ctx->rr_pipe->res_com)
ctx->rr_pipe->res_com->event_added = 0;
#endif
}
/* see if bg thread is created and if threads have been killed */
/* no locks, because those may be held by terminated threads */
/* for processes the read pipe is closed and we see that on read */
#ifdef HAVE_PTHREAD
if(ctx->created_bg && ctx->dothread) {
if(ctx->created_bg && ctx->dothread && do_stop) {
if(pthread_kill(ctx->bg_tid, 0) == ESRCH) {
/* thread has been killed */
do_stop = 0;
@@ -318,6 +338,23 @@ ub_ctx_delete(struct ub_ctx* ctx)
#endif /* HAVE_PTHREAD */
if(do_stop)
ub_stop_bg(ctx);
if(ctx->created_bg && ctx->pipe_pid != getpid() && ctx->thread_worker) {
/* This delete is happening from a different process. Delete
* the thread worker from this process memory space. The
* thread is not there to do so, so it is freed here. */
struct ub_event_base* evbase = comm_base_internal(
ctx->thread_worker->base);
libworker_delete_event(ctx->thread_worker);
ctx->thread_worker = NULL;
#ifdef USE_MINI_EVENT
ub_event_base_free(evbase);
#else
/* cannot event_base_free, because the epoll_fd cleanup
* in libevent could stop the original event_base in the
* other process from working. */
free(evbase);
#endif
}
libworker_delete_event(ctx->event_worker);
modstack_desetup(&ctx->mods, ctx->env);
+1 -2
View File
@@ -395,6 +395,7 @@ int libworker_bg(struct ub_ctx* ctx)
w = libworker_setup(ctx, 1, NULL);
if(!w) return UB_NOMEM;
w->is_bg_thread = 1;
ctx->thread_worker = w;
#ifdef ENABLE_LOCK_CHECKS
w->thread_num = 1; /* for nicer DEBUG checklocks */
#endif
@@ -604,8 +605,6 @@ setup_qinfo_edns(struct libworker* w, struct ctx_query* q,
edns->opt_list_out = NULL;
edns->opt_list_inplace_cb_out = NULL;
edns->padding_block_size = 0;
edns->cookie_present = 0;
edns->cookie_valid = 0;
if(sldns_buffer_capacity(w->back->udp_buff) < 65535)
edns->udp_size = (uint16_t)sldns_buffer_capacity(
w->back->udp_buff);
+2 -1
View File
@@ -230,7 +230,7 @@ int ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base);
* @param callback: this is called on completion of the resolution.
* It is called as:
* void callback(void* mydata, int rcode, void* packet, int packet_len,
* int sec, char* why_bogus)
* int sec, char* why_bogus, int was_ratelimited)
* with mydata: the same as passed here, you may pass NULL,
* with rcode: 0 on no error, nonzero for mostly SERVFAIL situations,
* this is a DNS rcode.
@@ -241,6 +241,7 @@ int ub_ctx_set_event(struct ub_ctx* ctx, struct event_base* base);
* with packet_len: length in bytes of the packet buffer.
* with sec: 0 if insecure, 1 if bogus, 2 if DNSSEC secure.
* with why_bogus: text string explaining why it is bogus (or NULL).
* with was_ratelimited: if the query was ratelimited.
* These point to buffers inside unbound; do not deallocate the packet or
* error string.
*
+29 -10
View File
@@ -255,7 +255,7 @@ cleanup:
int pythonmod_init(struct module_env* env, int id)
{
int py_mod_idx = py_mod_count++;
/* Initialize module */
FILE* script_py = NULL;
PyObject* py_init_arg, *res;
@@ -316,23 +316,37 @@ int pythonmod_init(struct module_env* env, int id)
if (py_mod_count==1) {
/* Initialize Python */
PyRun_SimpleString("import sys \n");
if(PyRun_SimpleString("import sys \n") < 0 ) {
goto python_init_fail;
}
PyRun_SimpleString("sys.path.append('.') \n");
PyRun_SimpleString("sys.path.append('"RUN_DIR"') \n");
PyRun_SimpleString("sys.path.append('"SHARE_DIR"') \n");
if(env->cfg->directory && env->cfg->directory[0]) {
char wdir[1524];
snprintf(wdir, sizeof(wdir), "sys.path.append('%s') \n",
env->cfg->directory);
PyRun_SimpleString(wdir);
}
PyRun_SimpleString("sys.path.append('"RUN_DIR"') \n");
PyRun_SimpleString("sys.path.append('"SHARE_DIR"') \n");
PyRun_SimpleString("import distutils.sysconfig \n");
PyRun_SimpleString("sys.path.append(distutils.sysconfig.get_python_lib(1,0)) \n");
if (PyRun_SimpleString("from unboundmodule import *\n") < 0)
/* Check if sysconfig is there and use that instead of distutils;
* distutils.sysconfig is deprecated in Python 3.10. */
if(PyRun_SimpleString("import sysconfig \n") < 0) {
log_info("pythonmod: module sysconfig not available; "
"falling back to distutils.sysconfig.");
if(PyRun_SimpleString("import distutils.sysconfig \n") < 0
|| PyRun_SimpleString("sys.path.append("
"distutils.sysconfig.get_python_lib(1,0)) \n") < 0) {
goto python_init_fail;
}
} else {
if(PyRun_SimpleString("sys.path.append("
"sysconfig.get_path('platlib')) \n") < 0) {
goto python_init_fail;
}
}
if(PyRun_SimpleString("from unboundmodule import *\n") < 0)
{
log_err("pythonmod: cannot initialize core module: unboundmodule.py");
PyGILState_Release(gil);
return 0;
goto python_init_fail;
}
}
@@ -480,6 +494,11 @@ int pythonmod_init(struct module_env* env, int id)
PyGILState_Release(gil);
return 1;
python_init_fail:
log_err("pythonmod: cannot initialize core module: unboundmodule.py");
PyGILState_Release(gil);
return 0;
}
void pythonmod_deinit(struct module_env* env, int id)
-4
View File
@@ -5419,8 +5419,6 @@ xfr_transfer_lookup_host(struct auth_xfer* xfr, struct module_env* env)
edns.opt_list_out = NULL;
edns.opt_list_inplace_cb_out = NULL;
edns.padding_block_size = 0;
edns.cookie_present = 0;
edns.cookie_valid = 0;
if(sldns_buffer_capacity(buf) < 65535)
edns.udp_size = (uint16_t)sldns_buffer_capacity(buf);
else edns.udp_size = 65535;
@@ -6614,8 +6612,6 @@ xfr_probe_lookup_host(struct auth_xfer* xfr, struct module_env* env)
edns.opt_list_out = NULL;
edns.opt_list_inplace_cb_out = NULL;
edns.padding_block_size = 0;
edns.cookie_present = 0;
edns.cookie_valid = 0;
if(sldns_buffer_capacity(buf) < 65535)
edns.udp_size = (uint16_t)sldns_buffer_capacity(buf);
else edns.udp_size = 65535;
+8
View File
@@ -636,6 +636,14 @@ tomsg(struct module_env* env, struct query_info* q, struct reply_info* r,
r->serve_expired_ttl < now) {
return NULL;
}
/* Ignore expired failure answers */
if(FLAGS_GET_RCODE(r->flags) !=
LDNS_RCODE_NOERROR &&
FLAGS_GET_RCODE(r->flags) !=
LDNS_RCODE_NXDOMAIN &&
FLAGS_GET_RCODE(r->flags) !=
LDNS_RCODE_YXDOMAIN)
return 0;
} else {
return NULL;
}
+5 -197
View File
@@ -230,7 +230,7 @@ setup_domain_limits(struct infra_cache* infra, struct config_file* cfg)
}
struct infra_cache*
infra_create(struct config_file* cfg, struct ub_randstate* rnd)
infra_create(struct config_file* cfg)
{
struct infra_cache* infra = (struct infra_cache*)calloc(1,
sizeof(struct infra_cache));
@@ -270,11 +270,6 @@ infra_create(struct config_file* cfg, struct ub_randstate* rnd)
infra_delete(infra);
return NULL;
}
if (!rnd) {
infra_delete(infra);
return NULL;
}
infra->random_state = rnd;
return infra;
}
@@ -304,7 +299,7 @@ infra_adjust(struct infra_cache* infra, struct config_file* cfg)
{
size_t maxmem;
if(!infra)
return infra_create(cfg, ub_initstate(NULL));
return infra_create(cfg);
infra->host_ttl = cfg->host_ttl;
infra->infra_keep_probing = cfg->infra_keep_probing;
infra_dp_ratelimit = cfg->ratelimit;
@@ -320,7 +315,7 @@ infra_adjust(struct infra_cache* infra, struct config_file* cfg)
!slabhash_is_size(infra->client_ip_rates, cfg->ip_ratelimit_size,
cfg->ip_ratelimit_slabs)) {
infra_delete(infra);
infra = infra_create(cfg, ub_initstate(NULL));
infra = infra_create(cfg);
} else {
/* reapply domain limits */
traverse_postorder(&infra->domain_limits, domain_limit_free,
@@ -383,36 +378,17 @@ infra_lookup_nottl(struct infra_cache* infra, struct sockaddr_storage* addr,
return slabhash_lookup(infra->hosts, k.entry.hash, &k, wr);
}
/* helper function to fill in random data into the client cookie*/
void infra_fill_client_cookie_random(struct infra_cache* infra,
uint8_t* data) {
int i;
for (i = 0; i < 8; i++) {
data[i] = ub_random_max(infra->random_state, 256);
}
}
/** init the data elements */
static void
data_entry_init(struct infra_cache* infra, struct lruhash_entry* e,
time_t timenow)
{
struct infra_data* data;
uint8_t client_cookie_data[8] = {0,0,0,0,0,0,0,0};
infra_fill_client_cookie_random(infra, client_cookie_data);
data = (struct infra_data*)e->data;
struct infra_data* data = (struct infra_data*)e->data;
data->ttl = timenow + infra->host_ttl;
rtt_init(&data->rtt);
data->edns_version = 0;
data->edns_lame_known = 0;
data->probedelay = 0;
/* set EDNS cookie to zero, as this also sets the starting state*/
memset(&data->cookie, 0, sizeof(struct edns_cookie));
data->cookie.pif.out = NULL;
memcpy(data->cookie.data.cookie, client_cookie_data, 8);
data->isdnsseclame = 0;
data->rec_lame = 0;
data->lame_type_A = 0;
@@ -483,11 +459,7 @@ infra_host(struct infra_cache* infra, struct sockaddr_storage* addr,
if(e) {
/* if its still there we have a writelock, init */
/* re-initialise */
// @TODO check if "do not touch lameness" is still true
/* do not touch lameness, it may be valid still.
* Also don't touch the cookie, as the cookie logic
* will be handled by the server. */
/* do not touch lameness, it may be valid still */
data_entry_init(infra, e, timenow);
wr = 1;
/* TOP_TIMEOUT remains on reuse */
@@ -713,170 +685,6 @@ infra_edns_update(struct infra_cache* infra, struct sockaddr_storage* addr,
return 1;
}
int
infra_get_cookie(struct infra_cache* infra, struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t* name, size_t namelen,
time_t timenow, struct edns_cookie* cookie, int renew)
{
struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
name, namelen, 1);
struct infra_data* data;
int needtoinsert = 0;
if(!e) {
if(!(e = new_entry(infra, addr, addrlen, name, namelen, timenow))) {
return 0;
}
needtoinsert = 1;
} else if(((struct infra_data*)e->data)->ttl < timenow) {
/* EDNS cookies have their own timeout logic controlled by the
* upstream, so we just copy the cookie from the old cache entry */
struct edns_cookie c = ((struct infra_data*)e->data)->cookie;
/* create new cookie if the cache TTL expired, keep the cookie */
data_entry_init(infra, e, timenow);
((struct infra_data*)e->data)->cookie = c;
}
data = (struct infra_data*) e->data;
/* renew cookie if the address that is stored isn't available */
if (renew == 1 || (data->cookie.pif.addrlen == 0 &&
data->cookie.state == SERVER_COOKIE_LEARNED)) {
infra_fill_client_cookie_random(infra, (uint8_t*) &data->cookie.data);
data->cookie.state = SERVER_COOKIE_UNKNOWN;
}
memcpy(cookie, &data->cookie, sizeof(struct edns_cookie));
if(needtoinsert) {
slabhash_insert(infra->hosts, e->hash, e, e->data, NULL);
} else {
lock_rw_unlock(&e->lock);
}
return 1;
}
int
infra_set_server_cookie(struct infra_cache* infra, struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t* name, size_t namelen, struct port_if *pif,
struct edns_option* cookie)
{
struct lruhash_entry* e = infra_lookup_nottl(infra, addr, addrlen,
name, namelen, 1);
struct infra_data* data;
/* cookie length verification should be checked and handled by caller */
assert(cookie->opt_len == 24);
/* the client cookie was set on the outgoing upstream, so the entry
* should exists here. This can be false if the cookie has fallen
* out of cache */
if (!(e)) {
/* No need to insert a new cookie/entry here, this will be
* done with an outgoing request */
return 0;
}
data = (struct infra_data*) e->data;
if (data->cookie.state == COOKIE_NOT_SUPPORTED) {
/* we known this upstream doesn't support cookies; the state
* remains unchanged */
lock_rw_unlock(&e->lock);
return 1;
} else if (data->cookie.state == SERVER_COOKIE_LEARNED) {
/* wrong client cookie; don't store the server cookie */
if (!(memcmp(data->cookie.data.cookie,
cookie->opt_data+4, 8))) {
/* the state of the cookie remains unchanged as we will
* drop this upstream response */
verbose(VERB_ALGO, "wrong client cookie from upstream"
" with previously seen cookie");
lock_rw_unlock(&e->lock);
return -1;
}
/* We set the local pif addrlen to 0 if the interface is not found
* so it must be unequal to the stored addrlen */
if (data->cookie.pif.addrlen != pif->addrlen &&
pif->addrlen == 0){
/* don't change the status, but change to cookie length
* so it gets renewed during the lookup (which is
* where all the cookie creation happens) */
data->cookie.pif.addrlen = 0;
lock_rw_unlock(&e->lock);
log_info("the interface to the upstream response server "
"that was bound to this EDNS cookie has changed;"
" renewing cookie");
return 0;
}
/* the server cookie has changed, but the client cookie has not
* so we update the server cookie */
if (memcmp(data->cookie.data.cookie+8,
cookie->opt_data+12, 16) != 0) {
memcpy(data->cookie.data.cookie, cookie->opt_data, 24);
/* the cookie state remains unchanged*/
verbose(VERB_ALGO, "update new server cookie from upstream");
lock_rw_unlock(&e->lock);
/* log_hex() uses the verbosity levels of verbose() */
log_hex("complete cookie: ", cookie->opt_data,
cookie->opt_len);
return 1;
}
/* both the complete cookies are identical, so the state
* remains unchanged */
verbose(VERB_ALGO, "correctly received indentical cookie from"
" upstream; don't update");
lock_rw_unlock(&e->lock);
/* log_hex() uses the verbosity levels of verbose() */
log_hex("complete cookie: ", cookie->opt_data,
cookie->opt_len);
return 1;
} else { /* cookie state == SERVER_COOKIE_UNKNOWN */
/* wrong client cookie; don't store the server cookie */
if (!(memcmp(data->cookie.data.cookie,
cookie->opt_data+4, 8))) {
/* the state of the cookie remains unchanged as we will
* drop this upstream response */
verbose(VERB_ALGO, "wrong client cookie from upstream");
lock_rw_unlock(&e->lock);
return -1;
}
/* store the server cookie */
memcpy(data->cookie.data.cookie, cookie->opt_data, 24);
data->cookie.state = SERVER_COOKIE_LEARNED;
/* store the inbound interface we receive this cookie on */
if (pif->addrlen > 0) {
memcpy(&data->cookie.pif,
pif, sizeof(struct port_if));
data->cookie.pif.addrlen = pif->addrlen;
}
verbose(VERB_QUERY, "storing received server cookie from upstream");
lock_rw_unlock(&e->lock);
/* log_hex() uses the verbosity levels of verbose() */
log_hex("complete cookie: ", cookie->opt_data,
cookie->opt_len);
return 1;
}
}
int
infra_get_lame_rtt(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen,
+1 -86
View File
@@ -49,51 +49,9 @@
#include "util/rtt.h"
#include "util/netevent.h"
#include "util/data/msgreply.h"
#include "services/outside_network.h"
struct slabhash;
struct config_file;
/* COOKIE @TODO move this to correct spot */
/**
* The actual EDNS cookie data. Note that the cookie can be filled with the
* just 'client' section, or with the 'complete' cookie depending on the state
* governed by the edns_cookie_state.
* The commented struct provides insight on how the bytes in the struct are
* structured.
*/
struct edns_cookie_data {
uint8_t cookie[24];
/* struct {
uint8_t client[8];
uint8_t version;
uint8_t reserved[3];
uint32_t timestamp;
uint8_t hash[8];
} components; */
};
/**
* The different states the EDNS cookie can be in
*/
enum edns_cookie_state
{
SERVER_COOKIE_UNKNOWN = 0, /* server cookie unknown, client cookie known */
SERVER_COOKIE_LEARNED = 1, /* server (and client) cookie known */
COOKIE_NOT_SUPPORTED = 2, /* upstream does not supported EDNS/cookies */
};
/**
* Structure for an EDNS cookie (RFC9018), it's internal state, and the
* the outgoing address that we bind this cookie to for privacy (RFC9018)
*/
struct edns_cookie {
enum edns_cookie_state state;
struct edns_cookie_data data;
struct port_if pif;
};
/**
* Host information kept for every server, per zone.
*/
@@ -130,9 +88,6 @@ struct infra_data {
* and cause a timeout */
uint8_t edns_lame_known;
/* The EDNS cookie containing the cookie and the internal state */
struct edns_cookie cookie;
/** is the host lame (does not serve the zone authoritatively),
* or is the host dnssec lame (does not serve DNSSEC data) */
uint8_t isdnsseclame;
@@ -167,8 +122,6 @@ struct infra_cache {
rbtree_type domain_limits;
/** hash table with query rates per client ip: ip_rate_key, ip_rate_data */
struct slabhash* client_ip_rates;
/** random state used in new entries for creating EDNS cookies (RFC9018) */
struct ub_randstate* random_state;
};
/** ratelimit, unless overridden by domain_limits, 0 is off */
@@ -243,7 +196,7 @@ struct rate_data {
* @param cfg: config parameters or NULL for defaults.
* @return: new infra cache, or NULL.
*/
struct infra_cache* infra_create(struct config_file* cfg, struct ub_randstate* rnd);
struct infra_cache* infra_create(struct config_file* cfg);
/**
* Delete infra cache.
@@ -365,44 +318,6 @@ int infra_edns_update(struct infra_cache* infra,
struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* name, size_t namelen, int edns_version, time_t timenow);
/**
* Find and return the cookie from the infra cache data. Creates an entry in
* the cache if there isn't one.
* @param infra: infrastructure cache.
* @param addr: host address.
* @param addrlen: length of addr.
* @param name: name of zone
* @param namelen: length of name
* @param timenow: what time it is now.
* @param pif: the interface which contains the outgoing address that we bind to
* @param cookie: the cookie that is retrieved from cache on success.
* @return: 0 on error, cookie pointer remains unchanged then.
*/
int infra_get_cookie(struct infra_cache* infra, struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t* name, size_t namelen,
time_t timenow, struct edns_cookie* cookie, int renew); //@TODO fix/remove renew?
/**
* Find the cookie entry in the cache and update it with to make a 'complete cookie'
* (client+server) (RFC9018). This function asserts that the cookie param contains
* a complete cookie with a length of 24 bytes. If the cache entry isn't found
* a new one will be inserted.
* @param infra: infrastructure cache.
* @param addr: host address.
* @param addrlen: length of addr.
* @param name: name of zone
* @param namelen: length of name
* @param timenow: what time it is now.
* @param pif: the interface which contains the outgoing address that we bind to
* @param cookie: the EDNS cookie option we want to store.
* @return -1 if the wrong client cookie is found, 0 if the entry isn't found in
* the cache and a new one is inserted, 1 if the complete cookie is inserted
* or unchanged.
*/
int infra_set_server_cookie(struct infra_cache* infra, struct sockaddr_storage* addr,
socklen_t addrlen, uint8_t* name, size_t namelen, struct port_if *pif,
struct edns_option* cookie);
/**
* Get Lameness information and average RTT if host is in the cache.
* This information is to be used for server selection.
+4 -4
View File
@@ -639,7 +639,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
&& !(errno == EADDRNOTAVAIL && verbosity < 4 && !listen)
#endif
) {
log_err_addr("1can't bind socket", strerror(errno),
log_err_addr("can't bind socket", strerror(errno),
(struct sockaddr_storage*)addr, addrlen);
}
#endif /* EADDRINUSE */
@@ -647,7 +647,7 @@ create_udp_sock(int family, int socktype, struct sockaddr* addr,
if(WSAGetLastError() != WSAEADDRINUSE &&
WSAGetLastError() != WSAEADDRNOTAVAIL &&
!(WSAGetLastError() == WSAEACCES && verbosity < 4 && !listen)) {
log_err_addr("2can't bind socket",
log_err_addr("can't bind socket",
wsa_strerror(WSAGetLastError()),
(struct sockaddr_storage*)addr, addrlen);
}
@@ -840,12 +840,12 @@ create_tcp_accept_sock(struct addrinfo *addr, int v6only, int* noproto,
if(addr->ai_family==AF_INET6 && errno==EINVAL)
*noproto = 1;
else {
log_err_addr("3can't bind socket", strerror(errno),
log_err_addr("can't bind socket", strerror(errno),
(struct sockaddr_storage*)addr->ai_addr,
addr->ai_addrlen);
}
#else
log_err_addr("4can't bind socket",
log_err_addr("can't bind socket",
wsa_strerror(WSAGetLastError()),
(struct sockaddr_storage*)addr->ai_addr,
addr->ai_addrlen);
-2
View File
@@ -886,8 +886,6 @@ void mesh_report_reply(struct mesh_area* mesh, struct outbound_entry* e,
event = module_event_noreply;
if(what == NETEVENT_CAPSFAIL)
event = module_event_capsfail;
if(what == NETEVENT_BOUND_INTERFACE_NOT_AVAILABLE)
event = module_event_interface_not_available;
}
mesh_run(mesh, e->qstate->mesh_info, event, e);
}
+8 -86
View File
@@ -1073,8 +1073,7 @@ reuse_tcp_remove_tree_list(struct outside_network* outnet,
char buf[256];
addr_to_str(&reuse->addr, reuse->addrlen, buf,
sizeof(buf));
log_err("reuse tcp delete: node not present, internal error, %s ssl "
"%d lru %d", buf, reuse->is_ssl, reuse->item_on_lru_list);
log_err("reuse tcp delete: node not present, internal error, %s ssl %d lru %d", buf, reuse->is_ssl, reuse->item_on_lru_list);
}
reuse->node.key = NULL;
/* defend against loops on broken tree by zeroing the
@@ -1419,7 +1418,6 @@ outnet_send_wait_udp(struct outside_network* outnet)
pend->pkt_len = 0;
log_assert(!pend->sq->busy);
pend->sq->busy = 1;
if(!randomize_and_send_udp(pend, outnet->udp_buff,
pend->timeout)) {
/* callback error on pending */
@@ -1444,11 +1442,6 @@ outnet_udp_cb(struct comm_point* c, void* arg, int error,
struct pending* p;
verbose(VERB_ALGO, "answer cb");
log_err("!!!!! outnet_udp_cb: HERE, error: %d", error);
// @TODO this is the function where we find the failed kernel call
if(error != NETEVENT_NOERROR) {
verbose(VERB_QUERY, "outnetudp got udp error %d", error);
return 0;
@@ -1490,7 +1483,6 @@ outnet_udp_cb(struct comm_point* c, void* arg, int error,
verbose(VERB_ALGO, "received udp reply.");
log_buf(VERB_ALGO, "udp message", c->buffer);
if(p->pc->cp != c) {
verbose(VERB_QUERY, "received reply id,addr on wrong port. "
"dropped.");
@@ -1981,9 +1973,6 @@ udp_sockport(struct sockaddr_storage* addr, socklen_t addrlen, int pfxlen,
int port, int* inuse, struct ub_randstate* rnd, int dscp)
{
int fd, noproto;
log_err("!!!!! udp_sockport: HERE!");
if(addr_is_ip6(addr, addrlen)) {
int freebind = 0;
struct sockaddr_in6 sa = *(struct sockaddr_in6*)addr;
@@ -2064,6 +2053,7 @@ static int udp_connect_needs_log(int err)
return 1;
}
/** Select random interface and port */
static int
select_ifport(struct outside_network* outnet, struct pending* pend,
@@ -2077,21 +2067,11 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
"outgoing interfaces of that family");
return 0;
}
log_assert(outnet->unused_fds);
tries = 0;
while(1) {
/* if we have a bound IP address for the EDNS cookie in the
* message, use that interface */
if (!(pend->sq->bound_interface)) {
my_if = ub_random_max(outnet->rnd, num_if);
pif = &ifs[my_if];
} else {
pif = pend->sq->bound_interface;
log_err("!!!!! select_ifport:bound_addrlen: %d", pif->addrlen);
log_addr(VERB_OPS, "!!!!! select_ifport:bound_addrlen:", &pif->addr, pif->addrlen);
}
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 */
@@ -2114,9 +2094,6 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
break;
}
}
log_err("!!!!! select_ifport:pif->inuse: %d, pif->maxout: %d", pif->inuse, pif->maxout);
/* 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];
@@ -2126,15 +2103,6 @@ select_ifport(struct outside_network* outnet, struct pending* pend,
fd = udp_sockport(&pif->addr, pif->addrlen, pif->pfxlen,
portno, &inuse, outnet->rnd, outnet->ip_dscp);
if(fd == -1 && !inuse) {
log_err("!!!! select_ifport:nonrecoverable error making socket");
/* we need to retry sending this message with a cookie
* without a bound interface. The cookie needs to be
* changed as to not leak the client cookie part that
* is linked to this outgoing interface. */
if (pend->sq->bound_interface != NULL) {
pend->sq->bound_interface_failed = 1;
}
/* nonrecoverable error making socket */
return 0;
}
@@ -2261,7 +2229,6 @@ pending_udp_query(struct serviced_query* sq, struct sldns_buffer* packet,
pend->cb = cb;
pend->cb_arg = cb_arg;
pend->node.key = pend;
pend->timer = comm_timer_create(sq->outnet->base, pending_udp_timer_cb,
pend);
if(!pend->timer) {
@@ -2598,7 +2565,6 @@ serviced_timer_cb(void* arg)
* will get attached by the time we get an answer. */
return;
delete:
log_err("!!!!! serviced_timer_cb:delete serviced_udp_send");
serviced_callbacks(sq, NETEVENT_CLOSED, NULL, NULL);
}
@@ -2609,7 +2575,7 @@ serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
char* tls_auth_name, struct sockaddr_storage* addr, socklen_t addrlen,
uint8_t* zone, size_t zonelen, int qtype, struct edns_option* opt_list,
size_t pad_queries_block_size, struct alloc_cache* alloc,
struct port_if* bound_interface, struct regional* region)
struct regional* region)
{
struct serviced_query* sq = (struct serviced_query*)malloc(sizeof(*sq));
struct timeval t;
@@ -2672,18 +2638,6 @@ serviced_create(struct outside_network* outnet, sldns_buffer* buff, int dnssec,
sq->status = serviced_initial;
sq->retry = 0;
sq->to_be_deleted = 0;
if (bound_interface != NULL) {
sq->bound_interface = regional_alloc_init(region,
bound_interface, sizeof(struct port_if));
if (!sq->bound_interface) {
alloc_reg_release(alloc, region);
free(sq);
return NULL;
}
} else {
sq->bound_interface = NULL;
}
sq->bound_interface_failed = 0;
sq->padding_block_size = pad_queries_block_size;
#ifdef UNBOUND_DEBUG
ins =
@@ -3050,12 +3004,6 @@ serviced_callbacks(struct serviced_query* sq, int error, struct comm_point* c,
}
sq->outnet->svcd_overhead = backlen;
}
/* set the error to retry the cookie with a new client cookie set */
if (sq->bound_interface != NULL && sq->bound_interface_failed) {
error = NETEVENT_BOUND_INTERFACE_NOT_AVAILABLE;
}
/* test the actual sq->cblist, because the next elem could be deleted*/
while((p=sq->cblist) != NULL) {
sq->cblist = p->next; /* remove this element */
@@ -3422,11 +3370,9 @@ outnet_serviced_query(struct outside_network* outnet,
struct service_callback* cb;
struct edns_string_addr* client_string_addr;
struct regional* region;
struct edns_cookie cookie;
struct edns_option* backed_up_opt_list = qstate->edns_opts_back_out;
struct edns_option* per_upstream_opt_list = NULL;
time_t timenow = 0;
struct port_if* pif = NULL;
/* If we have an already populated EDNS option list make a copy since
* we may now add upstream specific EDNS options. */
@@ -3463,28 +3409,6 @@ outnet_serviced_query(struct outside_network* outnet,
client_string_addr->string, region);
}
if (env->cfg->upstream_cookies &&
infra_get_cookie(env->infra_cache, addr, addrlen, zone, zonelen,
*env->now, &cookie, 0)) {
if (cookie.state == SERVER_COOKIE_LEARNED) {
/* We known the complete cookie, so we attach it */
edns_opt_list_append(&per_upstream_opt_list, LDNS_EDNS_COOKIE,
24, cookie.data.cookie, region);
if (cookie.pif.addrlen > 0) {
pif = &cookie.pif;
log_addr(VERB_DETAIL, "!!!!! outnet_serviced_query:pif addr:", &cookie.pif.addr, cookie.pif.addrlen);
}
} else if (cookie.state == SERVER_COOKIE_UNKNOWN) {
/* We know just client cookie, so we attach it */
edns_opt_list_append(&per_upstream_opt_list, LDNS_EDNS_COOKIE,
8, cookie.data.cookie, region);
} /* We ignore COOKIE_NOT_SUPPORTED */
}
serviced_gen_query(buff, qinfo->qname, qinfo->qname_len, qinfo->qtype,
qinfo->qclass, flags);
sq = lookup_serviced(outnet, buff, dnssec, addr, addrlen,
@@ -3517,7 +3441,7 @@ outnet_serviced_query(struct outside_network* outnet,
per_upstream_opt_list,
( ssl_upstream && env->cfg->pad_queries
? env->cfg->pad_queries_block_size : 0 ),
env->alloc, pif, region);
env->alloc, region);
if(!sq) {
if(check_ratelimit) {
infra_ratelimit_dec(env->infra_cache,
@@ -3607,8 +3531,7 @@ fd_for_dest(struct outside_network* outnet, struct sockaddr_storage* to_addr,
if(outnet->num_ip6 == 0) {
char to[64];
addr_to_str(to_addr, to_addrlen, to, sizeof(to));
verbose(VERB_QUERY, "need ipv6 to send, but no ipv6 outgoing "
"interfaces, for %s", to);
verbose(VERB_QUERY, "need ipv6 to send, but no ipv6 outgoing interfaces, for %s", to);
return -1;
}
i = ub_random_max(outnet->rnd, outnet->num_ip6);
@@ -3617,8 +3540,7 @@ fd_for_dest(struct outside_network* outnet, struct sockaddr_storage* to_addr,
if(outnet->num_ip4 == 0) {
char to[64];
addr_to_str(to_addr, to_addrlen, to, sizeof(to));
verbose(VERB_QUERY, "need ipv4 to send, but no ipv4 outgoing "
"interfaces, for %s", to);
verbose(VERB_QUERY, "need ipv4 to send, but no ipv4 outgoing interfaces, for %s", to);
return -1;
}
i = ub_random_max(outnet->rnd, outnet->num_ip4);
-7
View File
@@ -527,13 +527,6 @@ struct serviced_query {
struct comm_timer* timer;
/** true if serviced_query is currently doing net I/O and may block */
int busy;
/** interface bound to the EDNS cookie @TODO fix this */
struct port_if* bound_interface;
/** flag to create a retry when the opening of the socket on the
* bound interface failed. This enables rewriting of the cookie without
* leaking the previously sent client cookie */
int bound_interface_failed;
};
/**
+2 -6
View File
@@ -196,8 +196,8 @@ enum sldns_enum_rr_type
LDNS_RR_TYPE_OPENPGPKEY = 61, /* RFC 7929 */
LDNS_RR_TYPE_CSYNC = 62, /* RFC 7477 */
LDNS_RR_TYPE_ZONEMD = 63, /* draft-ietf-dnsop-dns-zone-digest-12 */
LDNS_RR_TYPE_SVCB = 64, /* draft-ietf-dnsop-svcb-https-04 */
LDNS_RR_TYPE_HTTPS = 65, /* draft-ietf-dnsop-svcb-https-04 */
LDNS_RR_TYPE_SVCB = 64, /* draft-ietf-dnsop-svcb-https-04 */
LDNS_RR_TYPE_HTTPS = 65, /* draft-ietf-dnsop-svcb-https-04 */
LDNS_RR_TYPE_SPF = 99, /* RFC 4408 */
@@ -433,7 +433,6 @@ enum sldns_enum_edns_option
LDNS_EDNS_DHU = 6, /* RFC6975 */
LDNS_EDNS_N3U = 7, /* RFC6975 */
LDNS_EDNS_CLIENT_SUBNET = 8, /* RFC7871 */
LDNS_EDNS_COOKIE = 10, /* RFC7873 */
LDNS_EDNS_KEEPALIVE = 11, /* draft-ietf-dnsop-edns-tcp-keepalive*/
LDNS_EDNS_PADDING = 12, /* RFC7830 */
LDNS_EDNS_EDE = 15, /* RFC8914 */
@@ -483,9 +482,6 @@ typedef enum sldns_enum_ede_code sldns_ede_code;
#define LDNS_TSIG_ERROR_BADNAME 20
#define LDNS_TSIG_ERROR_BADALG 21
/** DNS Cookie extended rcode */
#define LDNS_EXT_RCODE_BADCOOKIE 23
/**
* Contains all information about resource record types.
*
-1
View File
@@ -192,7 +192,6 @@ static sldns_lookup_table sldns_edns_options_data[] = {
{ 6, "DHU" },
{ 7, "N3U" },
{ 8, "edns-client-subnet" },
{ 10, "Cookie" },
{ 11, "edns-tcp-keepalive"},
{ 12, "Padding" },
{ 15, "EDE"},
+8 -4
View File
@@ -102,6 +102,12 @@ usage(void)
printf(" stop stops the server\n");
printf(" reload reloads the server\n");
printf(" (this flushes data, stats, requestlist)\n");
printf(" reload_keep_cache reloads the server but tries to\n");
printf(" keep the RRset and message cache\n");
printf(" if (re)configuration allows for it.\n");
printf(" That means the caches sizes and\n");
printf(" the number of threads must not\n");
printf(" change between reloads.\n");
printf(" stats print statistics\n");
printf(" stats_noreset peek at statistics\n");
#ifdef HAVE_SHMGET
@@ -180,8 +186,6 @@ usage(void)
#ifdef HAVE_SHMGET
/** what to put on statistics lines between var and value, ": " or "=" */
#define SQ "="
/** if true, inhibits a lot of =0 lines from the stats output */
static const int inhibit_zero = 1;
/** divide sum of timers to get average */
static void
timeval_divide(struct timeval* avg, const struct timeval* sum, long long d)
@@ -316,7 +320,7 @@ static void print_hist(struct ub_stats_info* s)
}
/** print extended */
static void print_extended(struct ub_stats_info* s)
static void print_extended(struct ub_stats_info* s, int inhibit_zero)
{
int i;
char nm[16];
@@ -439,7 +443,7 @@ static void do_stats_shm(struct config_file* cfg, struct ub_stats_info* stats,
if(cfg->stat_extended) {
print_mem(shm_stat, &stats[0]);
print_hist(stats);
print_extended(stats);
print_extended(stats, cfg->stat_inhibit_zero);
}
}
#endif /* HAVE_SHMGET */
-24
View File
@@ -1228,9 +1228,6 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
struct edns_option* backed_up_opt_list =
qstate->edns_opts_back_out;
struct edns_option* per_upstream_opt_list = NULL;
struct edns_cookie cookie;
struct port_if* pif;
/* If we have an already populated EDNS option list make a copy
* since we may now add upstream specific EDNS options. */
if(qstate->edns_opts_back_out) {
@@ -1259,25 +1256,6 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
client_string_addr->string_len,
client_string_addr->string, qstate->region);
}
if (qstate->env->cfg->upstream_cookies &&
infra_get_cookie(env->infra_cache, addr, addrlen,
zone, zonelen, *env->now, outnet, &pif, &cookie)) {
if (cookie.state == SERVER_COOKIE_LEARNED) {
/* We known the complete cookie, so we attach it */
edns_opt_list_append(&per_upstream_opt_list,
LDNS_EDNS_COOKIE, 24, cookie.data.cookie,
qstate->region);
} else if (cookie.state == SERVER_COOKIE_UNKNOWN) {
/* We know just client cookie, so we attach it */
edns_opt_list_append(&per_upstream_opt_list,
LDNS_EDNS_COOKIE, 8,
cookie.data.cookie,
qstate->region);
} /* We ignore COOKIE_NOT_SUPPORTED */
}
/* add edns */
edns.edns_present = 1;
edns.ext_rcode = 0;
@@ -1287,8 +1265,6 @@ struct serviced_query* outnet_serviced_query(struct outside_network* outnet,
if(dnssec)
edns.bits = EDNS_DO;
edns.padding_block_size = 0;
edns.cookie_present = 0;
edns.cookie_valid = 0;
edns.opt_list_in = NULL;
edns.opt_list_out = per_upstream_opt_list;
edns.opt_list_inplace_cb_out = NULL;
-243
View File
@@ -25,7 +25,6 @@ struct sockaddr_storage;
#include <errno.h>
#include <stdarg.h>
#include <ctype.h>
#include <time.h>
#include "testcode/testpkts.h"
#include "util/net_help.h"
#include "sldns/sbuffer.h"
@@ -40,8 +39,6 @@ struct sockaddr_storage;
#define MAX_LINE 10240
/** string to show in warnings and errors */
static const char* prog_name = "testpkts";
/** hardcoded EDNS server cookie (RFC7876) */
static const char* hardcoded_server_cookie = "7e8b5fcc6a4bc7bc";
#ifndef UTIL_LOG_H
/** verbosity definition for compat */
@@ -143,13 +140,6 @@ static void matchline(char* line, struct entry* e)
e->match_noedns = 1;
} else if(str_keyword(&parse, "ednsdata")) {
e->match_ednsdata_raw = 1;
} else if(str_keyword(&parse, "random_client_cookie")) {
e->match_random_client_cookie = 1;
} else if (str_keyword(&parse, "random_complete_cookie_renewed")) {
e->match_random_complete_cookie = 1;
e->match_random_complete_cookie_renewed = 1;
} else if(str_keyword(&parse, "random_complete_cookie")) {
e->match_random_complete_cookie = 1;
} else if(str_keyword(&parse, "UDP")) {
e->match_transport = transport_udp;
} else if(str_keyword(&parse, "TCP")) {
@@ -273,11 +263,6 @@ static void adjustline(char* line, struct entry* e,
pkt->packet_sleep = (unsigned int) strtol(parse, (char**)&parse, 10);
while(isspace((unsigned char)*parse))
parse++;
} else if (str_keyword(&parse, "server_cookie_renew")) {
e->server_cookie = 1;
e->server_cookie_renew = 1;
} else if (str_keyword(&parse, "server_cookie")) {
e->server_cookie = 1;
} else {
error("could not parse ADJUST: '%s'", parse);
}
@@ -314,8 +299,6 @@ static struct entry* new_entry(void)
e->copy_ednsdata_assume_clientsubnet = 0;
e->increment_ecs_scope = 0;
e->sleeptime = 0;
e->server_cookie = 0;
e->server_cookie_renew = 0;
e->next = NULL;
return e;
}
@@ -1516,110 +1499,6 @@ match_ednsdata(uint8_t* q, size_t qlen, uint8_t* p, size_t plen)
return (memcmp(walk_p+8, walk_q+8, walk_qlen-8) == 0);
}
/** verify that a client cookie of length 8 is in the EDNS data of the query */
static int
match_random_client_cookie(uint8_t* query, size_t query_len)
{
uint8_t* walk_query = query;
size_t walk_query_len = query_len;
if(!pkt_find_edns_opt(&walk_query, &walk_query_len)) {
walk_query_len = 0;
log_err("no edns found");
}
/* class + ttl + rdlen = 8 */
if (walk_query_len <= 8) {
verbose(3, "No correct EDNS record found, so no cookie");
return 0;
}
/* class + ttl + rdlen + opt_code + opt_len = 12 */
if (walk_query_len < 12) {
verbose(3, "No EDNS opt found, so no cookie");
return 0;
}
if (sldns_read_uint16(walk_query+8) != 10 /* LDNS_EDNS_COOKIE */) {
verbose(3, "EDNS option is not a cookie");
return 0;
}
if (sldns_read_uint16(walk_query+10) != 8) {
verbose(3, "EDNS cookie is not 8 bytes, so not a correct client cookie");
return 0;
}
return 1;
}
/** verify that a complete EDNS cookie (client+server) (RFC9018) of length 24
* is in the EDNS data of the query and the hardcoded cookie is the same */
static int
match_random_complete_cookie(uint8_t* query, size_t query_len, struct entry* p)
{
uint8_t* walk_query = query;
size_t walk_query_len = query_len;
if(!pkt_find_edns_opt(&walk_query, &walk_query_len)) {
walk_query_len = 0;
log_err("no edns found");
}
/* class + ttl + rdlen = 8 */
if(walk_query_len <= 8) {
verbose(3, "No correct EDNS record , so no cookie");
return 0;
}
walk_query += 8;
walk_query_len -= 8;
/* opt_code + opt_len = 4 */
if (walk_query_len < 4) {
verbose(3, "No EDNS opt found, so no cookie");
return 0;
}
if (sldns_read_uint16(walk_query) != 10 /* LDNS_EDNS_COOKIE */) {
verbose(3, "EDNS option is not a cookie");
return 0;
}
if (sldns_read_uint16(walk_query+2) != 24) {
verbose(3, "EDNS cookie is not 24 bytes, so not a correct complete cookie");
return 0;
}
/* opt_code + opt_len + cookie_data = 28 */
if (walk_query_len < 28) {
verbose(3, "No complete cookie found in the packet");
return 0;
}
if (p->match_random_complete_cookie_renewed) {
uint8_t renewed_cookie[16];
/* shuffle the hardcoded cookie like adjust_packet() does */
memcpy(renewed_cookie, hardcoded_server_cookie+8, 8);
memcpy(renewed_cookie+8, hardcoded_server_cookie, 8);
/* client_cookie = 8 */
if (!(memcmp(walk_query+8, renewed_cookie, 16))) {
verbose(3, "EDNS server cookie does not match the renewed"
"cookie, so not a correct complete cookie");
return 0;
}
}
/* client_cookie = 8 */
if (!(memcmp(walk_query+8, hardcoded_server_cookie, 16))) {
verbose(3, "EDNS server cookie does not match the hardcoded cookie, "
"so not a correct complete cookie");
return 0;
}
return 1;
}
/* finds entry in list, or returns NULL */
struct entry*
find_match(struct entry* entries, uint8_t* query_pkt, size_t len,
@@ -1715,16 +1594,6 @@ find_match(struct entry* entries, uint8_t* query_pkt, size_t len,
verbose(3, "bad EDNS data match.\n");
continue;
}
if (p->match_random_client_cookie &&
!match_random_client_cookie(query_pkt, len)) {
verbose(3, "bad client cookie match.\n");
continue;
}
if (p->match_random_complete_cookie &&
!match_random_complete_cookie(query_pkt, len, p)) {
verbose(3, "bad complete cookie match.\n");
continue;
}
if(p->match_transport != transport_any && p->match_transport != transport) {
verbose(3, "bad transport\n");
continue;
@@ -1821,118 +1690,6 @@ adjust_packet(struct entry* match, uint8_t** answer_pkt, size_t *answer_len,
if(match->copy_id && reslen >= 1 && query_len >= 1)
res[0] = query_pkt[0];
if(match->server_cookie) {
/** Find the cookie option and add the server cookie if
* the client cookie is present and not already there */
uint8_t* walk_query = query_pkt;
size_t walk_query_len = query_len;
uint8_t* walk_response;
size_t walk_response_len;
uint8_t* rdlen_ptr_response;
/* create space for the server cookie in the response packet */
res = realloc(res, reslen + 28);
reslen += 28;
walk_response = res;
walk_response_len = reslen;
if (!(walk_response)) {
log_err("testbound: out of memory; send without cookie");
return;
}
/* verify that we have a EDNS record */
if(!pkt_find_edns_opt(&walk_query, &walk_query_len)) {
walk_query_len = 0;
log_err("testbound: no EDNS in the query packet when "
"trying to attach a EDNS cookie");
}
if(!pkt_find_edns_opt(&walk_response, &walk_response_len)) {
walk_response_len = 0;
log_err("testbound: no EDNS in the response packet when"
"trying to attach a EDNS cookie");
}
/* verify that we have a EDNS option */
if (walk_query_len < 12) /* class + ttl + rdlen + opt_code + opt_len */ {
/* invalid or no (OPT) record in the query */
walk_query_len = 0;
log_err("testbound: invalid or no OPT record in the query packet");
}
if (walk_response_len < 8) /* class + ttl + rdlen */ {
walk_response_len = 0;
log_err("testbound: invalid OPT record in the response packet");
}
/* store the location of the rdlen */
rdlen_ptr_response = walk_response + 6;
/* skip past the OPT record to get to the option */
walk_query += 8;
walk_query_len -= 8;
walk_response += 8;
walk_response_len -= 8;
/* verify that the client cookie exists */
if (walk_query_len < 12 /* opt_code + opt_len + client cookie */) {
walk_query_len = 0;
log_err("testbound: no EDNS cookie in the query packet");
}
/* assume one record in the query */
if (sldns_read_uint16(walk_query) != 10 /* LDNS_EDNS_COOKIE */ ||
!(sldns_read_uint16(walk_query+2) == 8 || /* client cookie length */
sldns_read_uint16(walk_query+2) == 24)) { /* client+server cookie */
/* incorrect cookie */
walk_query_len = 0;
log_err("testbound: invalid EDNS cookie in the query packet");
}
if (walk_query_len > 0 && walk_response_len > 0) {
/* create space for the cookie, as the length of the
* rest of the response is 0 */
/* depending on the incoming cookie, add the server cookie
* or copy the complete cookie to the response */
if (sldns_read_uint16(walk_query+2) == 8) {
/* copy the EDNS client cookie from the query
* packet to the response */
memmove(walk_response, walk_query, 12);
/* add the server cookie to the client cookie to make it
* 'complete'. we fake the siphash specified in RFC9018
* by hardcoding the server cookie */
memmove(walk_response+12, hardcoded_server_cookie, 16);
/* update the RDLEN and OPTLEN */
sldns_write_uint16(rdlen_ptr_response, 28);
sldns_write_uint16(walk_response+2, 24);
} else if (sldns_read_uint16(walk_query+2) == 24) {
/* update the RDLEN */
sldns_write_uint16(rdlen_ptr_response, 28);
/* we fake verification of the cookie and send
* it back like it's still valid. We renew the cookie
* if this desired */
if (match->server_cookie_renew) {
/* copy the cookie from the response but add a
* different cookie (by reshuffeling server cookie) */
memmove(walk_response, walk_query, 12);
memmove(walk_response+12, walk_query+12+8, 8);
memmove(walk_response+12+8, walk_query+12, 8);
} else {
memmove(walk_response, walk_query, 28);
}
} else {
log_err("testbound: the incoming EDNS cookie has the wrong length");
}
} else {
log_err("testbound: an error has occured while parsing the EDNS cookie");
}
}
if(match->copy_ednsdata_assume_clientsubnet) {
/** Assume there is only one EDNS option, which is ECS.
* Copy source mask from query to scope mask in reply. Assume
-16
View File
@@ -214,14 +214,6 @@ struct entry {
uint8_t match_noedns;
/** match edns data field given in hex */
uint8_t match_ednsdata_raw;
/** match an EDNS cookie (RFC7873) of length 8*/
uint8_t match_random_client_cookie;
/** match an EDNS cookie (RFC7873) of length 24, we call
* this "complete" (RFC9018) */
uint8_t match_random_complete_cookie;
/** match an EDNS compelete cookie (RFC7873) of length 24, which cannot be
* the same as the hardcoded client cookie */
uint8_t match_random_complete_cookie_renewed;
/** match query serial with this value. */
uint32_t ixfr_soa_serial;
/** match on UDP/TCP */
@@ -245,14 +237,6 @@ struct entry {
/** in seconds */
unsigned int sleeptime;
/** add a server cookie (RFC9018) to the response (provided the query
* contains a client cookie) */
uint8_t server_cookie;
/** renew the server cookie (RFC9018) to the response (provided the query
* contains a client cookie) by shuffling the bytes in the server cookie
* Note that this also sets "server_cookie" to 1*/
uint8_t server_cookie_renew;
/** some number that names this entry, line number in file or so */
int lineno;
+1 -3
View File
@@ -469,12 +469,11 @@ infra_test(void)
struct infra_key* k;
struct infra_data* d;
int init = 376;
struct ub_randstate* rnd = ub_initstate(NULL);
unit_show_feature("infra cache");
unit_assert(ipstrtoaddr("127.0.0.1", 53, &one, &onelen));
slab = infra_create(cfg, rnd);
slab = infra_create(cfg);
unit_assert( infra_host(slab, &one, onelen, zone, zonelen, now,
&vs, &edns_lame, &to) );
unit_assert( vs == 0 && to == init && edns_lame == 0 );
@@ -529,7 +528,6 @@ infra_test(void)
infra_delete(slab);
config_delete(cfg);
ub_randfree(rnd);
}
#include "util/random.h"
+5 -2
View File
@@ -1,6 +1,6 @@
server:
verbosity: 2
# num-threads: 1
num-threads: 1
interface: 127.0.0.1
port: @PORT@
use-syslog: no
@@ -9,6 +9,10 @@ server:
chroot: ""
username: ""
do-not-query-localhost: no
access-control: 127.0.0.1 allow_snoop
msg-cache-size: 4m
rrset-cache-size: 4m
minimal-responses: yes
remote-control:
control-enable: yes
control-interface: 127.0.0.1
@@ -21,4 +25,3 @@ remote-control:
forward-zone:
name: "."
forward-addr: "127.0.0.1@@TOPORT@"
+279 -335
View File
@@ -5,364 +5,317 @@
[ -f .tpkg.var.test ] && source .tpkg.var.test
PRE="../.."
. ../common.sh
# exit value is 1 on usage
$PRE/unbound-control -h
if test $? -ne 1; then
echo "wrong exit value for usage."
exit 1
else
echo "exit value for usage: OK"
fi
# End the test
# $1: exit value
end () {
echo "> cat logfiles"
cat fwd.log
cat unbound.log
exit $1
}
# Expect a given exit value of the previous command
# $1: the expected exit value
# $2: optional text to print when failing
expect_exit_value () {
if test $? -ne $1; then
if test -z "$2"; then
if test $1 -eq 1; then
msg="on error"
else
msg="after success"
fi
else
msg="$2"
fi
echo "wrong exit value $msg"
end 1
fi
}
# Helper function for quering
# $@: at least the domain name to query and optional dig arguments
query () {
echo "> dig $@"
dig @127.0.0.1 -p $UNBOUND_PORT $@ | tee outfile
}
# Expect something in the answer
# $1: expected regular expression
expect_answer () {
echo "> check answer for \"$1\""
if grep "$1" outfile; then
echo "OK"
else
echo "Not OK"
end 1
fi
}
# Fail the test for unexpected answers
# $1: unexpected regular expression
fail_answer () {
echo "> \"$1\" should not be in answer"
if grep "$1" outfile; then
echo "Not OK"
end 1
else
echo "OK"
fi
}
# Issue an unbound-control command
# $@: command arguments
control_command () {
echo "$PRE/unbound-control $@"
$PRE/unbound-control $@ > outfile
}
# Dump the cache contents
# $@: optional options to unbound-control
cache_dump () {
echo "$PRE/unbound-control $@ dump_cache > cache.dump"
$PRE/unbound-control $@ dump_cache > cache.dump
}
# Load cache contents
# $@: optional options to unbound-control
cache_load () {
echo "$PRE/unbound-control $@ load_cache < cache.dump"
$PRE/unbound-control $@ load_cache < cache.dump
}
# Expect an entry in the cache dump
# $1: expected regular expression
expect_in_cache_dump () {
echo "> check cache dump for \"$1\""
if grep "$1" cache.dump; then
echo "OK cache dump"
else
echo "Not OK cache dump"
end 1
fi
}
# Fail the test for unexpected entry in the cache dump
# $1: unexpected regular expression
fail_in_cache_dump () {
echo "> \"$1\" should not be in cache dump"
if grep "$1" cache.dump; then
echo "Not OK cache dump"
end 1
else
echo "OK cache dump"
fi
}
# start the test
cp ub.conf main.conf
teststep "exit value is 1 on usage"
control_command -h
expect_exit_value 1 "for usage"
# use lock-verify if possible
# test if the server is up.
echo "> dig www.example.com."
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
echo "> check answer"
if grep "10.20.30.40" outfile; then
echo "OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
teststep "test if the server is up"
query www.example.com.
expect_answer "10.20.30.40"
# exit value is 1 when a bad command is given.
echo "$PRE/unbound-control -c ub.conf blablargh"
$PRE/unbound-control -c ub.conf blablargh
if test $? -ne 1; then
echo "wrong exit value on error."
echo "> cat logfiles"
cat fwd.log
cat unbound.lo
exit 1
else
echo "correct exit value on error"
fi
teststep "exit value is 1 when a bad command is given"
control_command -c ub.conf blablargh
expect_exit_value 1
# reload the server. test if the server came up by putting a new
# local-data element in the server.
teststep "reload the server"
echo "server: local-data: 'afterreload. IN A 5.6.7.8'" >> ub.conf
echo "$PRE/unbound-control -c ub.conf reload"
$PRE/unbound-control -c ub.conf reload
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
control_command -c ub.conf reload
expect_exit_value 0
query afterreload.
expect_answer "5.6.7.8"
echo "> dig afterreload."
dig @127.0.0.1 -p $UNBOUND_PORT afterreload. | tee outfile
echo "> check answer"
if grep "5.6.7.8" outfile; then
echo "OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
teststep "must have had at least 1 query since reload"
control_command -c ub.conf stats
expect_exit_value 0
expect_answer "^total.num.queries=[1-9][0-9]*$"
# must have had queries now. 1 since reload.
echo "$PRE/unbound-control -c ub.conf stats"
$PRE/unbound-control -c ub.conf stats > tmp.$$
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
if grep "^total.num.queries=[1-9][0-9]*$" tmp.$$; then
echo "OK"
else
echo "bad stats"
cat tmp.$$
exit 1
fi
teststep "check verbosity"
control_command -c ub.conf verbosity 2
expect_exit_value 0
# verbosity
echo "$PRE/unbound-control -c ub.conf verbosity 2"
$PRE/unbound-control -c ub.conf verbosity 2
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
teststep "check syntax error in parse"
control_command -c ub.conf verbosity jkdf
expect_exit_value 1
# check syntax error in parse
echo "$PRE/unbound-control -c ub.conf verbosity jkdf"
$PRE/unbound-control -c ub.conf verbosity jkdf
if test $? -ne 1; then
echo "wrong exit value after failure"
exit 1
fi
# check bad credentials
teststep "check bad credentials"
cp ub.conf bad.conf
echo "remote-control:" >> bad.conf
echo " server-key-file: bad_server.key" >> bad.conf
echo " server-cert-file: bad_server.pem" >> bad.conf
echo " control-key-file: bad_control.key" >> bad.conf
echo " control-cert-file: bad_control.pem" >> bad.conf
echo "$PRE/unbound-control -c bad.conf verbosity 2"
$PRE/unbound-control -c bad.conf verbosity 2
if test $? -ne 1; then
echo "wrong exit value after failure"
exit 1
fi
cat conf.bad_credentials >> bad.conf
control_command -c bad.conf verbosity 2
expect_exit_value 1
# check spoofedclient credentials
teststep "check spoofed client credentials"
rm -f bad.conf
cp ub.conf bad.conf
echo "remote-control:" >> bad.conf
echo " server-key-file: unbound_server.key" >> bad.conf
echo " server-cert-file: unbound_server.pem" >> bad.conf
echo " control-key-file: bad_control.key" >> bad.conf
echo " control-cert-file: bad_control.pem" >> bad.conf
echo "$PRE/unbound-control -c bad.conf verbosity 2"
$PRE/unbound-control -c bad.conf verbosity 2
if test $? -ne 1; then
echo "wrong exit value after failure"
exit 1
fi
cat conf.spoofed_credentials >> bad.conf
control_command -c bad.conf verbosity 2
expect_exit_value 1
# create a new local zone
echo "> test of local zone"
echo "$PRE/unbound-control -c ub.conf local_zone example.net static"
$PRE/unbound-control -c ub.conf local_zone example.net static
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
echo "$PRE/unbound-control -c ub.conf local_data www.example.net A 192.0.2.1"
$PRE/unbound-control -c ub.conf local_data www.example.net A 192.0.2.1
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
teststep "create a new local zone"
control_command -c ub.conf local_zone example.net static
expect_exit_value 0
control_command -c ub.conf local_data www.example.net A 192.0.2.1
expect_exit_value 0
# check that www.example.net exists
echo "> dig www.example.net."
dig @127.0.0.1 -p $UNBOUND_PORT www.example.net. | tee outfile
echo "> check answer"
if grep "192.0.2.1" outfile; then
echo "OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
teststep "check that www.example.net exists"
query www.example.net.
expect_answer "192.0.2.1"
# check that mail.example.net has nxdomain
echo "> dig mail.example.net."
dig @127.0.0.1 -p $UNBOUND_PORT mail.example.net. | tee outfile
echo "> check answer"
if grep "NXDOMAIN" outfile; then
echo "OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
teststep "check that mail.example.net has nxdomain"
query mail.example.net.
expect_answer "NXDOMAIN"
# remove www.example.net - check it gets nxdomain
echo "$PRE/unbound-control -c ub.conf local_data_remove www.example.net"
$PRE/unbound-control -c ub.conf local_data_remove www.example.net
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
echo "> dig www.example.net."
dig @127.0.0.1 -p $UNBOUND_PORT www.example.net. | tee outfile
echo "> check answer"
if grep "NXDOMAIN" outfile; then
echo "OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
teststep "remove www.example.net - check it gets nxdomain"
control_command -c ub.conf local_data_remove www.example.net
expect_exit_value 0
query www.example.net.
expect_answer "NXDOMAIN"
# remove nonexistent name - check bug#287(segfault) does not happen.
echo "$PRE/unbound-control -c ub.conf local_data_remove test.example.net"
$PRE/unbound-control -c ub.conf local_data_remove test.example.net
teststep "remove nonexistent name - check bug#287(segfault) does not happen"
control_command -c ub.conf local_data_remove test.example.net
# if crash then then we get: error: could not SSL_read from unbound-control
if test $? -ne 0; then
echo "wrong exit value after success"
cat unbound.log
echo "Not OK"
exit 1
fi
expect_exit_value 0
# remove example.net - check its gone.
echo "$PRE/unbound-control -c ub.conf local_zone_remove example.net"
$PRE/unbound-control -c ub.conf local_zone_remove example.net
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
echo "> dig www.example.net."
dig @127.0.0.1 -p $UNBOUND_PORT www.example.net. | tee outfile
echo "> check answer"
if grep "SERVFAIL" outfile; then
echo "OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
teststep "remove example.net - check its gone"
control_command -c ub.conf local_zone_remove example.net
expect_exit_value 0
query www.example.net.
expect_answer "SERVFAIL"
# dump the cache
echo "> test cache dump"
# fillup cache
echo "dig www.example.com"
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com.
echo "$PRE/unbound-control -c ub.conf dump_cache"
$PRE/unbound-control -c ub.conf dump_cache > tmp.$$
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
cat tmp.$$
if grep 10.20.30.40 tmp.$$; then
echo "OK example.com is in cache dump"
else
echo "Not OK cache dump"
exit 1
fi
teststep "dump the cache"
query www.example.com.
cache_dump -c ub.conf
expect_exit_value 0
cat cache.dump
expect_in_cache "10.20.30.40"
# test lookup
echo "$PRE/unbound-control -c ub.conf lookup www.example.com"
$PRE/unbound-control -c ub.conf lookup www.example.com
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
control_command -c ub.conf lookup www.example.com
expect_exit_value 0
# answer to lookup is meaningless because of use a forwarder, oh well.
# load the cache dump.
echo "$PRE/unbound-control -c ub.conf load_cache < tmp.$$"
$PRE/unbound-control -c ub.conf load_cache < tmp.$$
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
echo "> dig www.example.com."
dig @127.0.0.1 -p $UNBOUND_PORT www.example.com. | tee outfile
echo "> check answer"
if grep "10.20.30.40" outfile; then
echo "OK"
else
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "Not OK"
exit 1
fi
teststep "load the cache dump"
cache_load -c ub.conf
expect_exit_value 0
query www.example.com.
expect_answer "10.20.30.40"
# load local-zones from file
echo "$PRE/unbound-control -c ub.conf local_zones < local_zones"
$PRE/unbound-control -c ub.conf local_zones < local_zones
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
echo "> dig localzonefromfile."
dig @127.0.0.1 -p $UNBOUND_PORT localzonefromfile | tee outfile
echo "> check answer"
if grep "REFUSED" outfile; then
echo "OK"
else
echo "Not OK"
exit 1
fi
teststep "load local-zones from file"
control_command -c ub.conf local_zones < local_zones
expect_exit_value 0
query localzonefromfile
expect_answer "REFUSED"
# load local-data from file
echo "$PRE/unbound-control -c ub.conf local_datas < local_data"
$PRE/unbound-control -c ub.conf local_datas < local_data
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
echo "> dig localdatafromfile."
dig @127.0.0.1 -p $UNBOUND_PORT -t txt localdatafromfile | tee outfile
echo "> check answer"
if grep "local data from file OK" outfile; then
echo "OK"
else
echo "Not OK"
exit 1
fi
teststep "load local-data from file"
control_command -c ub.conf local_datas < local_data
expect_exit_value 0
query -t txt localdatafromfile
expect_answer "local data from file OK"
# remove local-zone and local-data from file
echo "$PRE/unbound-control -c ub.conf local_zones_remove < local_zones_remove"
$PRE/unbound-control -c ub.conf local_zones_remove < local_zones_remove
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
echo "$PRE/unbound-control -c ub.conf local_datas_remove < local_data_remove"
$PRE/unbound-control -c ub.conf local_datas_remove < local_data_remove
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
echo "> check zone and data removal list_local_zones"
$PRE/unbound-control -c ub.conf list_local_zones | tee outfile
if grep "localzonefromfile" outfile; then
echo "Not OK"
exit 1
fi
if grep "local data from file OK" outfile; then
echo "Not OK"
exit 1
fi
if grep "otherlocalzone" outfile; then
echo "OK"
else
echo "Not OK"
exit 1
fi
teststep "remove local-zone and local-data from file"
control_command -c ub.conf local_zones_remove < local_zones_remove
expect_exit_value 0
control_command -c ub.conf local_datas_remove < local_data_remove
expect_exit_value 0
control_command -c ub.conf list_local_zones
fail_answer "localzonefromfile"
fail_answer "local data from file OK"
expect_answer "otherlocalzone"
# flushing
echo "$PRE/unbound-control -c ub.conf flush www.example.net"
$PRE/unbound-control -c ub.conf flush www.example.net
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
teststep "flushing"
control_command -c ub.conf flush www.example.net
expect_exit_value 0
control_command -c ub.conf flush_type www.example.net TXT
expect_exit_value 0
control_command -c ub.conf flush_zone example.net
expect_exit_value 0
echo "$PRE/unbound-control -c ub.conf flush_type www.example.net TXT"
$PRE/unbound-control -c ub.conf flush_type www.example.net TXT
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
teststep "reload the server for a clean state and populate the cache"
cp main.conf ub.conf
control_command -c ub.conf reload
expect_exit_value 0
query www.example.com
expect_answer "10.20.30.40"
echo "$PRE/unbound-control -c ub.conf flush_zone example.net"
$PRE/unbound-control -c ub.conf flush_zone example.net
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
teststep "reload and check cache dump - should be empty"
control_command -c ub.conf reload
expect_exit_value 0
cache_dump -c ub.conf
expect_exit_value 0
fail_in_cache_dump "www.example.com.*10.20.30.40"
fail_in_cache_dump "msg www.example.com. IN A"
# now stop the server
echo "$PRE/unbound-control -c ub.conf stop"
$PRE/unbound-control -c ub.conf stop
if test $? -ne 0; then
echo "wrong exit value after success"
exit 1
fi
# see if the server has really exited.
query www.example.com
expect_answer "10.20.30.40"
teststep "reload_keep_cache and check cache dump - should not be empty"
control_command -c ub.conf reload_keep_cache
expect_exit_value 0
cache_dump -c ub.conf
expect_exit_value 0
expect_in_cache_dump "www.example.com.*10.20.30.40"
expect_in_cache_dump "msg www.example.com. IN A"
query www.example.com +nordflag
expect_answer "10.20.30.40"
teststep "change msg-cache-size and reload_keep_cache - should be empty"
echo "server: msg-cache-size: 2m" >> ub.conf
control_command -c ub.conf reload_keep_cache
expect_exit_value 0
cache_dump -c ub.conf
expect_exit_value 0
fail_in_cache_dump "www.example.com.*10.20.30.40"
fail_in_cache_dump "msg www.example.com. IN A"
query www.example.com
expect_answer "10.20.30.40"
teststep "change rrset-cache-size and reload_keep_cache - should be empty"
echo "server: rrset-cache-size: 2m" >> ub.conf
control_command -c ub.conf reload_keep_cache
expect_exit_value 0
cache_dump -c ub.conf
expect_exit_value 0
fail_in_cache_dump "www.example.com.*10.20.30.40"
fail_in_cache_dump "msg www.example.com. IN A"
query www.example.com
expect_answer "10.20.30.40"
teststep "change num-threads and reload_keep_cache - should be empty"
echo "server: num-threads: 2" >> ub.conf
control_command -c ub.conf reload_keep_cache
expect_exit_value 0
cache_dump -c ub.conf
expect_exit_value 0
fail_in_cache_dump "www.example.com.*10.20.30.40"
fail_in_cache_dump "msg www.example.com. IN A"
query www.example.com
expect_answer "10.20.30.40"
teststep "change minimal-responses and reload_keep_cache - should not be empty"
echo "server: minimal-responses: no" >> ub.conf
control_command -c ub.conf reload_keep_cache
expect_exit_value 0
cache_dump -c ub.conf
expect_exit_value 0
expect_in_cache_dump "www.example.com.*10.20.30.40"
expect_in_cache_dump "msg www.example.com. IN A"
teststep "now stop the server"
control_command -c ub.conf stop
expect_exit_value 0
teststep "see if the server has really exited"
TRY_MAX=20
for (( try=0 ; try <= $TRY_MAX ; try++ )) ; do
if kill -0 $UNBOUND_PID 2>&1 | tee tmp.$$; then
@@ -379,11 +332,8 @@ for (( try=0 ; try <= $TRY_MAX ; try++ )) ; do
done
if kill -0 $UNBOUND_PID; then
echo "still up!"
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "not stopped, failure"
exit 1
end 1
else
echo "stopped OK"
@@ -392,15 +342,9 @@ else
echo "lock-verify test worked."
else
echo "lock-verify test failed."
cat fwd.log
cat unbound.log
exit 1
end 1
fi
fi
fi
echo "> cat logfiles"
cat fwd.log
cat unbound.log
echo "> OK"
exit 0
end 0
+5
View File
@@ -0,0 +1,5 @@
remote-control:
server-key-file: bad_server.key
server-cert-file: bad_server.pem
control-key-file: bad_control.key
control-cert-file: bad_control.pem
@@ -0,0 +1,5 @@
remote-control:
server-key-file: unbound_server.key
server-cert-file: unbound_server.pem
control-key-file: bad_control.key
control-cert-file: bad_control.pem
+6
View File
@@ -29,6 +29,7 @@
# wait_server_up_or_fail: wait for server to come up or print a failure string
# skip_test x : print message and skip test (must be called in .pre)
# kill_pid : kill a server, make sure and wait for it to go down.
# teststep : print the current test step in the output
# print error and exit
@@ -272,3 +273,8 @@ set_doxygen_path () {
fi
}
# Print the current test step in the output
teststep () {
echo
echo "STEP [ $1 ]"
}
-234
View File
@@ -1,234 +0,0 @@
; config options
server:
upstream-cookies: yes
stub-zone:
name: example.com
stub-addr: 1.1.1.1
CONFIG_END
SCENARIO_BEGIN Test edns-upstream-cookies
; Scenario overview:
; - Send a client cookie to the upstream and receive one back and store it
; - Send the client+server (complete) cookie and receive it back.
; - pass time and send the old complete cookie and receive a new one back
; Client query for upstream to Unbound
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
a.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
; Check that we send a server cookie to the upstream
STEP 2 CHECK_OUT_QUERY
ENTRY_BEGIN
MATCH qname qtype random_client_cookie
SECTION QUESTION
a.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
; Reply with a server cookie
STEP 3 REPLY
ENTRY_BEGIN
REPLY QR NOERROR
ADJUST copy_id server_cookie
SECTION QUESTION
a.example.com. IN A
SECTION ANSWER
a.example.com. IN A 1.2.3.4
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
; Check the answer from Unbound for the client
STEP 4 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA RD NOERROR
SECTION QUESTION
a.example.com. IN A
SECTION ANSWER
a.example.com. IN A 1.2.3.4
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
; Query a second time to verify that we have the server cookie stored
; Client query for upstream to Unbound
STEP 11 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
b.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
; Check that we send a server cookie to the upstream
STEP 12 CHECK_OUT_QUERY
ENTRY_BEGIN
MATCH qname qtype random_complete_cookie
SECTION QUESTION
b.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
; Reply with a server cookie
STEP 13 REPLY
ENTRY_BEGIN
REPLY QR NOERROR
ADJUST copy_id server_cookie
SECTION QUESTION
b.example.com. IN A
SECTION ANSWER
b.example.com. IN A 1.2.3.4
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
; Check the answer from Unbound for the client
STEP 14 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA RD NOERROR
SECTION QUESTION
b.example.com. IN A
SECTION ANSWER
b.example.com. IN A 1.2.3.4
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
; Query a third time while waiting more than hour + 5 minutes, so we should
; have a new cookie
STEP 20 TIME_PASSES ELAPSE 4000
; Client query for upstream to Unbound
STEP 21 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
c.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
; Check that we send a server cookie to the upstream
STEP 22 CHECK_OUT_QUERY
ENTRY_BEGIN
MATCH qname qtype random_complete_cookie
SECTION QUESTION
c.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
; Reply with an updated server cookie that
STEP 23 REPLY
ENTRY_BEGIN
REPLY QR NOERROR
ADJUST copy_id server_cookie_renew
SECTION QUESTION
c.example.com. IN A
SECTION ANSWER
c.example.com. IN A 1.2.3.4
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
; Check the answer from Unbound for the client
STEP 24 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA RD NOERROR
SECTION QUESTION
c.example.com. IN A
SECTION ANSWER
c.example.com. IN A 1.2.3.4
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
; Verify that the cookie was updated since the timestep
; Client query for upstream to Unbound
STEP 31 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
d.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
; Check that we send a server cookie to the upstream
STEP 32 CHECK_OUT_QUERY
ENTRY_BEGIN
MATCH qname qtype random_complete_cookie_renewed
SECTION QUESTION
d.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
; Reply with an updated server cookie that
STEP 33 REPLY
ENTRY_BEGIN
REPLY QR NOERROR
ADJUST copy_id server_cookie_renew
SECTION QUESTION
d.example.com. IN A
SECTION ANSWER
d.example.com. IN A 1.2.3.4
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
; Check the answer from Unbound for the client
STEP 34 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RA RD NOERROR
SECTION QUESTION
d.example.com. IN A
SECTION ANSWER
d.example.com. IN A 1.2.3.4
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
HEX_EDNSDATA_END
ENTRY_END
SCENARIO_END
@@ -1,16 +0,0 @@
BaseName: edns_upstream_cookies
Version: 1.0
Description: Test Upstream cookies with changing interfaces
CreationDate: Fri Aug 20 15:42:11 UTC 2021
Maintainer: Tom Carpay
Category:
Component:
CmdDepends:
Depends:
Help:
Pre: edns_upstream_cookies.pre
Post: edns_upstream_cookies.post
Test: edns_upstream_cookies.test
AuxFiles:
Passed:
Failure:
@@ -1,13 +0,0 @@
# #-- edns_upstream_cookies.post --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
# teardown
. ../common.sh
kill_pid $UNBOUND_PID
kill_pid $UNBOUND_PID2
# remove virtual interface
ip link del veth0 type veth peer name veth1
@@ -1,52 +0,0 @@
# #-- edns_upstream_cookies.pre --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
. ../common.sh
get_random_port 2
UNBOUND_PORT=$RND_PORT
UNBOUND2_PORT=$(($RND_PORT + 1))
echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
echo "NSD_PORT=$NSD_PORT" >> .tpkg.var.test
UPSTREAM_IP=10.0.0.1
UB_IP1=192.128.123.121
UB_IP2=192.128.123.122
echo "UPSTREAM_IP=$UPSTREAM_IP" >> .tpkg.var.test
echo "UB_IP1=$UB_IP1" >> .tpkg.var.test
echo "UB_IP2=$UB_IP2" >> .tpkg.var.test
# rewrite config file with created ports
sed -e 's/@PORT\@/'$UNBOUND_PORT'/' < unbound.conf > ub.conf
sed -e 's/@PORT2\@/'$UNBOUND2_PORT'/' < unbound_auth.conf > temp2.conf
sed -e 's/@IP2\@/'$UPSTREAM_IP'/' < temp2.conf > ub2.conf
# create virtual interfaces
ip link add veth0 type veth peer name veth1
ip link add veth0 type veth peer name veth1
ip link set dev veth0 up
ip link set dev veth1 up
ip addr add $UPSTREAM_IP dev veth0
ip addr add $UB_IP1 dev veth1
# start unbound in the background
PRE="../.."
$PRE/unbound -d -c ub.conf > unbound.log 2>&1 &
UNBOUND_PID=$!
echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
# start nsd in the background (for downstream cookies)
$PRE/unbound -d -c ub2.conf > unbound2.log 2>&1 &
UNBOUND_PID2=$!
echo "UNBOUND_PID2=$UNBOUND_PID2" >> .tpkg.var.test
cat .tpkg.var.test
wait_unbound_up unbound.log
wait_unbound_up unbound2.log
@@ -1,102 +0,0 @@
# #-- edns_upstream_cookies.test --#
# source the master var file when it's there
[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
# use .tpkg.var.test for in test variable passing
[ -f .tpkg.var.test ] && source .tpkg.var.test
# The problem of this test lies in that we want to look at the connection between
# the resolver and the upstream. I cannot think of a way for this to be done
# without either tcpdump or looking at the logs of the upstream.
# Plan of action
# @TODO Merge upstream cookies into this branch
# Create two IP addresses on 1 interface. Put one of them up and one of them down
# Start Unbound on this interface
# Get Unbound to send an upstream query (with a cookie)
# check the (complete) cookie in the log of the upstream and store the outgoing interface
# Send another query where we check that it is the same cookie
# verify that it is the same cookie and verify that the interface is the same
# @TODO we could do the time skip here as well. see edns_upstream_cookies.rpl
# take the interface down, send the query again
# Verify there is a different (client) cookie and that the interface has changed
# @TODO There could be a logic mishap in the final step as the flow is quite difficult now
#NSD_IP=192.128.123.120
# UB_IP3=192.128.123.123
# UB_IP4=192.128.123.124
# ip addr add $UB_IP2 dev veth1
# ip addr add $UB_IP3 dev veth1
# ip addr add $UB_IP4 dev veth1
# start cookie connection by sending first message
dig @$UNBOUND -p 9999 example.nl
# check Unbound logs that we got a "complete" (client+server) cookie back
sed -n "s/^.*complete cookie: \[24:0\] *//p" unbound.log > first_query.txt
if ! grep -e "complete cookie: [24:0] " grep_test.txt
then
echo "No complete cookie in the response to the first upstream query"
exit 1
fi
# check on which interface
IFACE=sed -n -e "s/^.*\!\!\!\!\! iterator:udp socket: *//" -e "s/ port.*//p" unbound.log
# flush unbound log
echo > unbound.log
# bring up second interface so we verify it keep using the first interface
ip addr add $UB_IP2 dev veth1
# send second query with the previous complete cookie attached
dig @$UNBOUND -p 9999 example.nl
# check logs that we get the same complete cookie back
sed -n "s/^.*complete cookie: \[24:0\] *//p" unbound.log > second_query.txt
if ! grep -e "complete cookie: [24:0] " grep_test.txt
then
echo "No complete cookie in the response to the second upstream query"
exit 1
fi
if [ "$(md5sum < first_query.txt)" != "$(md5sum < second_query.txt)" ]; then
echo "Cookies from the first and second query do not match"
cat first_query.txt
cat second_query.txt
exit 1
fi
# check on which interface, MUST be the same as last time
if [ "$(sed -n -e "s/^.*\!\!\!\!\! iterator:udp socket: *//" -e "s/ port.*//p" unbound.log) != $IFACE" ]
# remove the first interface so the kernel will have to use the second interface
ip addr del $UB_IP1 dev veth1
# flush unbound log
echo > unbound.log
dig @$UNBOUND -p 9999 example.nl
# check logs that we get the same complete cookie back
sed -n "s/^.*complete cookie: \[24:0\] *//p" unbound.log > second_query.txt
if ! grep -e "complete cookie: [24:0] " grep_test.txt
then
echo "No complete cookie in the response to the second upstream query"
exit 1
fi
# !!!!!! interface unavailable, renewing cookie
# send query (on different interface) with different (!) client cookie
# verify that we get a different client cookie in the complete cookie response
# verify that the cookie was indeed sent on a different interface
-16
View File
@@ -1,16 +0,0 @@
$ORIGIN example.nl.
$TTL 86400 ; default time-to-live for this zone
example.nl. IN SOA ns.example.nl. noc.dns.icann.org. (
2020080302 ;Serial
7200 ;Refresh
3600 ;Retry
1209600 ;Expire
3600 ;Negative response caching TTL
)
; The nameserver that are authoritative for this zone.
NS example.nl.
; these A records below are equivalent
example.nl. A 1.2.3.4
-17
View File
@@ -1,17 +0,0 @@
server:
verbosity: 2
use-syslog: no
chroot: ""
username: ""
directory: ""
pidfile: "unbound.pid"
interface: 127.0.0.1
port: @PORT1@
val-log-level: 2
upstream-cookies: yes
forward-zone:
name: "example.nl"
forward-addr: 127.0.0.1@9998
forward-no-cache: yes
-16
View File
@@ -1,16 +0,0 @@
server:
verbosity: 1
use-syslog: no
chroot: ""
username: ""
directory: ""
pidfile: "unbound2.pid"
interface: @UPSTREAM_IP@
port: @PORT2@
answer-cookie: yes
cookie-secret: "e5e973e5a6b2a43f48e7dc849e37bfcf"
auth-zone:
name: example.nl
zonefile: example.nl.zone
+2 -1
View File
@@ -2,6 +2,7 @@
; config options go here.
server:
serve-expired: yes
prefetch: yes
forward-zone: name: "." forward-addr: 216.0.0.1
CONFIG_END
@@ -45,7 +46,7 @@ SECTION ANSWER
ENTRY_END
; enough to pass by the TTL of the servfail answer in cache
STEP 50 TIME_PASSES ELAPSE 40
STEP 50 TIME_PASSES ELAPSE 5
; this query triggers a prefetch
STEP 210 QUERY
+144
View File
@@ -0,0 +1,144 @@
; config options
server:
target-fetch-policy: "0 0 0 0 0"
log-time-ascii: yes
fake-sha1: yes
trust-anchor-signaling: no
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
AUTOTRUST_FILE example.com
; autotrust trust anchor file
;;id: example.com. 1
;;last_queried: 1258962400 ;;Mon Nov 23 07:46:40 2009
;;last_success: 1258962400 ;;Mon Nov 23 07:46:40 2009
;;next_probe_time: 1258967360 ;;Mon Nov 23 09:09:20 2009
;;query_failed: 0
;;query_interval: 5400
;;retry_time: 3600
PUBKEY01 ;;state=2 [ VALID ] ;;count=0 ;;lastchange=1258962400 ;;Mon Nov 23 07:46:40 2009
PUBKEY02 ;;state=2 [ VALID ] ;;count=0 ;;lastchange=1258962400 ;;Mon Nov 23 07:46:40 2009
AUTOTRUST_END
CONFIG_END
SCENARIO_BEGIN Test autotrust with 10 keys
; spec says you must be able to handle at least 5 keys per trust point
; K-ROOT
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id copy_query
REPLY QR AA
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS k.root-servers.net.
SECTION ADDITIONAL
k.root-servers.net IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR
SECTION QUESTION
com. IN NS
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR
SECTION QUESTION
example.com. IN NS
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 0 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR AA
SECTION QUESTION
example.com. IN DNSKEY
SECTION ANSWER
PUBKEY01 ;;state=2 [ VALID ] ;;count=0 ;;lastchange=1258962400 ;;Mon Nov 23 07:46:40 2009
PUBKEY02 ;;state=2 [ VALID ] ;;count=0 ;;lastchange=1258962400 ;;Mon Nov 23 07:46:40 2009
PUBKEY03
PUBKEY04
PUBKEY05
PUBKEY06
PUBKEY07
PUBKEY08
PUBKEY09
PUBKEY10
PUBKEY11
PUBKEY12
PUBKEY13
SIG1
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. IN A 10.20.30.40
ENTRY_END
RANGE_END
; set date/time to Mon Nov 23 09:46:40 2009
STEP 5 TIME_PASSES EVAL ${1258962400 + 7200}
STEP 6 TRAFFIC ; do the probe
STEP 7 ASSIGN t0 = ${time}
STEP 8 ASSIGN probe0 = ${range 3200 ${timeout} 5400}
STEP 9 ASSIGN tp = ${1258962400}
; the auto probing should have been done now.
STEP 11 CHECK_AUTOTRUST example.com
FILE_BEGIN
; autotrust trust anchor file
;;id: example.com. 1
;;last_queried: ${$t0} ;;${ctime $t0}
;;last_success: ${$t0} ;;${ctime $t0}
;;next_probe_time: ${$t0 + $probe0} ;;${ctime $t0 + $probe0}
;;query_failed: 0
;;query_interval: 3600
;;retry_time: 3600
PUBKEY13 ;;state=1 [ ADDPEND ] ;;count=1 ;;lastchange=${$t0} ;;${ctime $t0}
PUBKEY12 ;;state=1 [ ADDPEND ] ;;count=1 ;;lastchange=${$t0} ;;${ctime $t0}
PUBKEY11 ;;state=1 [ ADDPEND ] ;;count=1 ;;lastchange=${$t0} ;;${ctime $t0}
PUBKEY10 ;;state=1 [ ADDPEND ] ;;count=1 ;;lastchange=${$t0} ;;${ctime $t0}
PUBKEY09 ;;state=1 [ ADDPEND ] ;;count=1 ;;lastchange=${$t0} ;;${ctime $t0}
PUBKEY08 ;;state=1 [ ADDPEND ] ;;count=1 ;;lastchange=${$t0} ;;${ctime $t0}
PUBKEY07 ;;state=1 [ ADDPEND ] ;;count=1 ;;lastchange=${$t0} ;;${ctime $t0}
PUBKEY06 ;;state=1 [ ADDPEND ] ;;count=1 ;;lastchange=${$t0} ;;${ctime $t0}
PUBKEY05 ;;state=1 [ ADDPEND ] ;;count=1 ;;lastchange=${$t0} ;;${ctime $t0}
PUBKEY04 ;;state=1 [ ADDPEND ] ;;count=1 ;;lastchange=${$t0} ;;${ctime $t0}
PUBKEY03 ;;state=1 [ ADDPEND ] ;;count=1 ;;lastchange=${$t0} ;;${ctime $t0}
PUBKEY02 ;;state=2 [ VALID ] ;;count=0 ;;lastchange=1258962400 ;;Mon Nov 23 07:46:40 2009
PUBKEY01 ;;state=2 [ VALID ] ;;count=0 ;;lastchange=1258962400 ;;Mon Nov 23 07:46:40 2009
FILE_END
SCENARIO_END
+306
View File
@@ -0,0 +1,306 @@
; config options
server:
target-fetch-policy: "0 0 0 0 0"
log-time-ascii: yes
fake-sha1: yes
trust-anchor-signaling: no
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
; initial content (say from dig example.com DNSKEY > example.com.key)
AUTOTRUST_FILE example.com
PUBKEY1
PUBKEY2
AUTOTRUST_END
CONFIG_END
SCENARIO_BEGIN Test autotrust with ADDPEND twice and exceeded time
; should work even though not signed with old key at latest time.
; K-ROOT
RANGE_BEGIN 0 100
ADDRESS 193.0.14.129
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id copy_query
REPLY QR AA
SECTION QUESTION
. IN NS
SECTION ANSWER
. IN NS k.root-servers.net.
SECTION ADDITIONAL
k.root-servers.net IN A 193.0.14.129
ENTRY_END
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR
SECTION QUESTION
com. IN NS
SECTION AUTHORITY
com. IN NS a.gtld-servers.net.
SECTION ADDITIONAL
a.gtld-servers.net. IN A 192.5.6.30
ENTRY_END
RANGE_END
; a.gtld-servers.net.
RANGE_BEGIN 0 100
ADDRESS 192.5.6.30
ENTRY_BEGIN
MATCH opcode subdomain
ADJUST copy_id copy_query
REPLY QR
SECTION QUESTION
example.com. IN NS
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
; ns.example.com. KSK PUBKEY1_ID
RANGE_BEGIN 0 10
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR AA
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 3600 IN A 10.20.30.40
SIG1a_PUBKEY2
SECTION AUTHORITY
example.com. 3600 IN NS ns.example.com.
SIG1b_PUBKEY2
SECTION ADDITIONAL
ns.example.com. 3600 IN A 1.2.3.4
SIG1c_PUBKEY2
ENTRY_END
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR AA
SECTION QUESTION
example.com. IN DNSKEY
SECTION ANSWER
; KSK 1
PUBKEY1
; ZSK 1
PUBKEY2
; signatures
SIG2_PUBKEY2
SIG2_PUBKEY1
ENTRY_END
RANGE_END
; ns.example.com. KSK PUBKEY1_ID and PUBKEY3_ID
RANGE_BEGIN 11 40
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR AA
SECTION QUESTION
example.com. IN DNSKEY
SECTION ANSWER
; KSK 1
PUBKEY1
; KSK 2
PUBKEY3
; ZSK 1
PUBKEY2
; signatures
SIG3_PUBKEY2
SIG3_PUBKEY1
SIG3_PUBKEY3
ENTRY_END
RANGE_END
; ns.example.com. KSK PUBKEY3_ID
RANGE_BEGIN 41 50
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR AA
SECTION QUESTION
example.com. IN DNSKEY
SECTION ANSWER
; KSK 2
PUBKEY3
; ZSK 1
PUBKEY2
; signatures
SIG4_PUBKEY2
SIG4_PUBKEY3
ENTRY_END
RANGE_END
; ns.example.com. KSK PUBKEY1_ID-REVOKED and PUBKEY3_ID
RANGE_BEGIN 51 60
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR AA
SECTION QUESTION
example.com. IN DNSKEY
SECTION ANSWER
; KSK 1
PUBKEY4
; KSK 2
PUBKEY3
; ZSK 1
PUBKEY2
; signatures
SIG5_PUBKEY2
SIG5_PUBKEY4
; wrong keytag:
SIG5_PUBKEY1
SIG5_PUBKEY3
ENTRY_END
RANGE_END
; ns.example.com. KSK PUBKEY3_ID
RANGE_BEGIN 61 70
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qname qtype
ADJUST copy_id
REPLY QR AA
SECTION QUESTION
example.com. IN DNSKEY
SECTION ANSWER
; KSK 2
PUBKEY3
; ZSK 1
PUBKEY2
; signatures
SIG6_PUBKEY2
SIG6_PUBKEY3
ENTRY_END
RANGE_END
; set date/time to Aug 24 07:46:40 (2009).
STEP 5 TIME_PASSES ELAPSE 1251100000
STEP 6 TRAFFIC ; the initial probe
STEP 7 ASSIGN t0 = ${time}
STEP 8 ASSIGN probe0 = ${range 4800 ${timeout} 5400}
; the auto probing should have been done now.
STEP 10 CHECK_AUTOTRUST example.com
FILE_BEGIN
; autotrust trust anchor file
;;id: example.com. 1
;;last_queried: ${$t0} ;;${ctime $t0}
;;last_success: ${$t0} ;;${ctime $t0}
;;next_probe_time: ${$t0 + $probe0} ;;${ctime $t0 + $probe0}
;;query_failed: 0
;;query_interval: 5400
;;retry_time: 3600
PUBKEY1 ;;state=2 [ VALID ] ;;count=0 ;;lastchange=${$t0} ;;${ctime $t0}
FILE_END
; key prepublished. First poll. 30 days later
STEP 11 TIME_PASSES EVAL ${30*24*3600}
STEP 12 TRAFFIC
STEP 13 ASSIGN t1 = ${time}
STEP 14 ASSIGN probe1 = ${range 4800 ${timeout} 5400}
STEP 15 CHECK_AUTOTRUST example.com
FILE_BEGIN
; autotrust trust anchor file
;;id: example.com. 1
;;last_queried: ${$t1} ;;${ctime $t1}
;;last_success: ${$t1} ;;${ctime $t1}
;;next_probe_time: ${$t1 + $probe1} ;;${ctime $t1 + $probe1}
;;query_failed: 0
;;query_interval: 5400
;;retry_time: 3600
PUBKEY3 ;;state=1 [ ADDPEND ] ;;count=1 ;;lastchange=${$t1} ;;${ctime $t1}
PUBKEY1 ;;state=2 [ VALID ] ;;count=0 ;;lastchange=${$t0} ;;${ctime $t0}
FILE_END
; Second poll. 10 days later
STEP 21 TIME_PASSES EVAL ${10*24*3600}
STEP 22 TRAFFIC
STEP 23 ASSIGN t2 = ${time}
STEP 24 ASSIGN probe2 = ${range 4800 ${timeout} 5400}
STEP 25 CHECK_AUTOTRUST example.com
FILE_BEGIN
; autotrust trust anchor file
;;id: example.com. 1
;;last_queried: ${$t2} ;;${ctime $t2}
;;last_success: ${$t2} ;;${ctime $t2}
;;next_probe_time: ${$t2 + $probe2} ;;${ctime $t2 + $probe2}
;;query_failed: 0
;;query_interval: 5400
;;retry_time: 3600
PUBKEY3 ;;state=1 [ ADDPEND ] ;;count=2 ;;lastchange=${$t1} ;;${ctime $t1}
PUBKEY1 ;;state=2 [ VALID ] ;;count=0 ;;lastchange=${$t0} ;;${ctime $t0}
FILE_END
; t3 is removed third poll time.
; 21 days later, hold down has lapsed.
STEP 41 TIME_PASSES EVAL ${21*24*3600}
STEP 42 TRAFFIC
STEP 43 ASSIGN t4 = ${time}
STEP 44 ASSIGN probe4 = ${range 4800 ${timeout} 5400}
STEP 45 CHECK_AUTOTRUST example.com
FILE_BEGIN
; autotrust trust anchor file
;;id: example.com. 1
;;last_queried: ${$t4} ;;${ctime $t4}
;;last_success: ${$t4} ;;${ctime $t4}
;;next_probe_time: ${$t4 + $probe4} ;;${ctime $t4 + $probe4}
;;query_failed: 0
;;query_interval: 5400
;;retry_time: 3600
PUBKEY3 ;;state=2 [ VALID ] ;;count=0 ;;lastchange=${$t4} ;;${ctime $t4}
PUBKEY1 ;;state=3 [ MISSING ] ;;count=0 ;;lastchange=${$t4} ;;${ctime $t4}
FILE_END
; 30 days later, the old key is revoked
STEP 51 TIME_PASSES EVAL ${30*24*3600}
STEP 52 TRAFFIC
STEP 53 ASSIGN t5 = ${time}
STEP 54 ASSIGN probe5 = ${range 4800 ${timeout} 5400}
STEP 55 CHECK_AUTOTRUST example.com
FILE_BEGIN
; autotrust trust anchor file
;;id: example.com. 1
;;last_queried: ${$t5} ;;${ctime $t5}
;;last_success: ${$t5} ;;${ctime $t5}
;;next_probe_time: ${$t5 + $probe5} ;;${ctime $t5 + $probe5}
;;query_failed: 0
;;query_interval: 5400
;;retry_time: 3600
PUBKEY3 ;;state=2 [ VALID ] ;;count=0 ;;lastchange=${$t4} ;;${ctime $t4}
PUBKEY4 ;;state=4 [ REVOKED ] ;;count=0 ;;lastchange=${$t5} ;;${ctime $t5}
FILE_END
; 370 days later, the old key is removed from storage
STEP 61 TIME_PASSES EVAL ${370*24*3600}
STEP 62 TRAFFIC
STEP 63 ASSIGN t6 = ${time}
STEP 64 ASSIGN probe6 = ${range 4800 ${timeout} 5400}
STEP 65 CHECK_AUTOTRUST example.com
FILE_BEGIN
; autotrust trust anchor file
;;id: example.com. 1
;;last_queried: ${$t6} ;;${ctime $t6}
;;last_success: ${$t6} ;;${ctime $t6}
;;next_probe_time: ${$t6 + $probe6} ;;${ctime $t6 + $probe6}
;;query_failed: 0
;;query_interval: 5400
;;retry_time: 3600
PUBKEY3 ;;state=2 [ VALID ] ;;count=0 ;;lastchange=${$t4} ;;${ctime $t4}
FILE_END
SCENARIO_END
+48
View File
@@ -0,0 +1,48 @@
#!/bin/sh
. ./gen-common
KEYNAME=autotrust_10key
replace_keys()
{
pubkey1=$(cat "$KEYDIR/$KEYNAME-1.key")
pubkey2=$(cat "$KEYDIR/$KEYNAME-2.key")
pubkey3=$(cat "$KEYDIR/$KEYNAME-3.key")
pubkey4=$(cat "$KEYDIR/$KEYNAME-4.key")
pubkey5=$(cat "$KEYDIR/$KEYNAME-5.key")
pubkey6=$(cat "$KEYDIR/$KEYNAME-6.key")
pubkey7=$(cat "$KEYDIR/$KEYNAME-7.key")
pubkey8=$(cat "$KEYDIR/$KEYNAME-8.key")
pubkey9=$(cat "$KEYDIR/$KEYNAME-9.key")
pubkey10=$(cat "$KEYDIR/$KEYNAME-10.key")
pubkey11=$(cat "$KEYDIR/$KEYNAME-11.key")
pubkey12=$(cat "$KEYDIR/$KEYNAME-12.key")
pubkey13=$(cat "$KEYDIR/$KEYNAME-13.key")
sed "s@PUBKEY01@$pubkey1@ ; \
s@PUBKEY02@$pubkey2@ ; \
s@PUBKEY03@$pubkey3@ ; \
s@PUBKEY04@$pubkey4@ ; \
s@PUBKEY05@$pubkey5@ ; \
s@PUBKEY06@$pubkey6@ ; \
s@PUBKEY07@$pubkey7@ ; \
s@PUBKEY08@$pubkey8@ ; \
s@PUBKEY09@$pubkey9@ ; \
s@PUBKEY10@$pubkey10@ ; \
s@PUBKEY11@$pubkey11@ ; \
s@PUBKEY12@$pubkey12@ ; \
s@PUBKEY13@$pubkey13@"
}
for i in 1 2 3 4 5 6 7 8 9 10 11 12 13
do
gen_key_ksk "$KEYDIR/$KEYNAME-$i"
done
sig1=$(sig_keys 2 20091124111500 20091018111500 1 2 3 4 5 6 7 8 9 10 11 12 13)
< autotrust_10key.rpl.in \
replace_keys |
sed "s@SIG1@$sig1@" \
> ../autotrust_10key.rpl
+78
View File
@@ -0,0 +1,78 @@
#!/bin/sh
. ./gen-common
KEYNAME=autotrust_addpend_2exceed
replace_keys()
{
pubkey1=$(cat "$KEYDIR/$KEYNAME-1.key")
pubkey2=$(cat "$KEYDIR/$KEYNAME-2.key")
pubkey3=$(cat "$KEYDIR/$KEYNAME-3.key")
pubkey4=$(cat "$KEYDIR/$KEYNAME-4.key")
pubkey1_id=$(key_id "$pubkey1")
pubkey3_id=$(key_id "$pubkey3")
sed "s@PUBKEY1_ID@$pubkey1_id@ ; \
s@PUBKEY3_ID@$pubkey3_id@ ; \
s@PUBKEY1@$pubkey1@ ; \
s@PUBKEY2@$pubkey2@ ; \
s@PUBKEY3@$pubkey3@ ; \
s@PUBKEY4@$pubkey4@"
}
gen_key_ksk "$KEYDIR/$KEYNAME-1"
gen_key_zsk "$KEYDIR/$KEYNAME-2"
gen_key_ksk "$KEYDIR/$KEYNAME-3"
gen_key_ksk_revoked "$KEYDIR/$KEYNAME-1" "$KEYDIR/$KEYNAME-4"
echo 'example.com. IN SOA host.example.com. user.example.com. (1 7200 3600 2419200 3600)' > $TMPZONE
echo 'www.example.com. 3600 IN A 10.20.30.40' >>$TMPZONE
echo 'example.com. 3600 IN NS ns.example.com.' >>$TMPZONE
echo 'ns.example.com. 3600 IN A 1.2.3.4' >>$TMPZONE
$LDNS_SIGNZONE -e 20090924111500 -i 20090821111500 $TMPZONE "$KEYDIR/$KEYNAME-2"
sig1a_pubkey2=$(grep 'www.example.com.*RRSIG[ ]*A' < $TMPZONE.signed )
sig1b_pubkey2=$(grep 'IN[ ]*RRSIG[ ]*NS[ ]' < $TMPZONE.signed )
sig1c_pubkey2=$(grep 'ns.example.com.*RRSIG[ ]*A' < $TMPZONE.signed )
rm -f "$TMPZONE" "$TMPZONE.signed"
sig2_pubkey2=$(sig_keys 2 20090924111500 20090821111500 1 2)
sig2_pubkey1=$(sig_keys 1 20090924111500 20090821111500 1 2)
sig3_pubkey2=$(sig_keys 2 20091024111500 20090921111500 1 3 2)
sig3_pubkey1=$(sig_keys 1 20091024111500 20090921111500 1 3 2)
sig3_pubkey3=$(sig_keys 3 20091024111500 20090921111500 1 3 2)
sig4_pubkey2=$(sig_keys 2 20091124111500 20091018111500 3 2)
sig4_pubkey3=$(sig_keys 3 20091124111500 20091018111500 3 2)
sig5_pubkey2=$(sig_keys 2 20091224111500 20091118111500 4 3 2)
sig5_pubkey4=$(sig_keys 4 20091224111500 20091118111500 4 3 2)
sig5_pubkey1=$(sig_keys 1 20091224111500 20091118111500 4 3 2)
sig5_pubkey3=$(sig_keys 3 20091224111500 20091118111500 4 3 2)
sig6_pubkey2=$(sig_keys 2 20101224111500 20101118111500 3 2)
sig6_pubkey3=$(sig_keys 3 20101224111500 20101118111500 3 2)
< $KEYNAME.rpl.in \
sed "s@SIG1a_PUBKEY2@$sig1a_pubkey2@ ; \
s@SIG1b_PUBKEY2@$sig1b_pubkey2@ ; \
s@SIG1c_PUBKEY2@$sig1c_pubkey2@ ; \
s@SIG2_PUBKEY2@$sig2_pubkey2@ ; \
s@SIG2_PUBKEY1@$sig2_pubkey1@ ; \
s@SIG3_PUBKEY2@$sig3_pubkey2@ ; \
s@SIG3_PUBKEY1@$sig3_pubkey1@ ; \
s@SIG3_PUBKEY3@$sig3_pubkey3@ ; \
s@SIG4_PUBKEY2@$sig4_pubkey2@ ; \
s@SIG4_PUBKEY3@$sig4_pubkey3@ ; \
s@SIG5_PUBKEY2@$sig5_pubkey2@ ; \
s@SIG5_PUBKEY4@$sig5_pubkey4@ ; \
s@SIG5_PUBKEY1@$sig5_pubkey1@ ; \
s@SIG5_PUBKEY3@$sig5_pubkey3@ ; \
s@SIG6_PUBKEY2@$sig6_pubkey2@ ; \
s@SIG6_PUBKEY3@$sig6_pubkey3@ ; \
" |
replace_keys \
> ../$KEYNAME.rpl
+107
View File
@@ -0,0 +1,107 @@
#!/bin/sh
KEYDIR=keys
LDNS_KEYGEN=ldns-keygen
LDNS_SIGNZONE=ldns-signzone
SECALG=8 # RSA/SHA-256
SECBITS=2048
TMPZONE=tmpzone
key_id()
{
expr "$1" : '.*{id = \([0-9]*\).*'
}
gen_key_ksk()
{
if [ $# -ne 1 ]; then
echo >&2 "Usage: gen_key_ksk <file-name>"
exit 1
fi
key_file="$1"
if [ -f "$key_file.key" ]
then
return # Key already exists, remove to regenerate
fi
mkdir -p "$KEYDIR"
tmp_keyname=$($LDNS_KEYGEN -a $SECALG -b $SECBITS -k example.com.)
sed 's/IN/10800 IN/' < "$tmp_keyname".key > "$key_file.key"
rm -f "$tmp_keyname".key
mv "$tmp_keyname".private "$key_file.private"
mv "$tmp_keyname".ds "$key_file.ds"
}
gen_key_ksk_revoked()
{
if [ $# -ne 2 ]; then
echo >&2 "Usage: gen_key_ksk_revoked <orig-file-name> <file-name>"
exit 1
fi
orig_key_file="$1"
key_file="$2"
if [ -f "$key_file.key" ]
then
return # Key already exists, remove to regenerate
fi
cp "$orig_key_file".key "$key_file".key
cp "$orig_key_file".private "$key_file.private"
mv "$orig_key_file".ds "$key_file.ds"
ldns-revoke "$key_file.key"
}
gen_key_zsk()
{
if [ $# -ne 1 ]; then
echo >&2 "Usage: gen_key_zsk <file-name>"
exit 1
fi
key_file="$1"
if [ -f "$key_file.key" ]
then
return # Key already exists, remove to regenerate
fi
mkdir -p "$KEYDIR"
tmp_keyname=$($LDNS_KEYGEN -a $SECALG -b $SECBITS example.com.)
sed 's/IN/10800 IN/' < "$tmp_keyname".key > "$key_file.key"
rm -f "$tmp_keyname".key
mv "$tmp_keyname".private "$key_file.private"
}
sig_keys()
{
if [ $# -lt 4 ]; then
echo >&2 'Usage: sig_keys <sig-key-nr> <endtime> <starttime> <key-nr>...'
exit 1
fi
sig_key_nr="$1"
shift
endtime="$1"
shift
starttime="$1"
shift
echo 'example.com. IN SOA host.example.com. user.example.com. (1 7200 3600 2419200 3600)' > $TMPZONE
while [ "$1" != "" ]
do
cat "$KEYDIR/$KEYNAME"-$1.key >> $TMPZONE
shift
done
$LDNS_SIGNZONE -e $endtime -i $starttime $TMPZONE "$KEYDIR/$KEYNAME-$sig_key_nr"
#echo '--- signed zone ---' >&2
#cat $TMPZONE.signed >&2
#echo '--- end signed zone ---' >&2
sig=$(grep 'RRSIG[ ]*DNSKEY' < $TMPZONE.signed )
rm -f "$TMPZONE" "$TMPZONE.signed"
echo "$sig"
}
+130
View File
@@ -0,0 +1,130 @@
; config options
server:
module-config: "validator iterator"
qname-minimisation: "no"
minimal-responses: no
serve-expired: yes
serve-expired-reply-ttl: 123
log-servfail: yes
ede: yes
ede-serve-expired: yes
stub-zone:
name: "example.com"
stub-addr: 1.2.3.4
CONFIG_END
SCENARIO_BEGIN Test serve-expired with client-timeout and a SERVFAIL upstream reply
; Scenario overview:
; - query for example.com. IN A
; - answer from upstream is SERVFAIL; will be cached for NORR_TTL(5)
; - check that the client gets the SERVFAIL; also cached
; - query again right after the TTL expired
; - cached SERVFAIL should be ignored and upstream queried
; - check that we get the correct answer
; ns.example.com.
RANGE_BEGIN 0 20
ADDRESS 1.2.3.4
; response to A query
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR AA SERVFAIL
SECTION QUESTION
example.com. IN A
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 30 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. 10 IN NS
SECTION ANSWER
example.com. 10 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 10 IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
SECTION AUTHORITY
example.com. 10 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 10 IN A 1.2.3.4
ENTRY_END
RANGE_END
; Query with RD flag
STEP 0 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
example.com. IN A
ENTRY_END
; Check that we get the SERVFAIL (will be cached)
STEP 10 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA SERVFAIL
SECTION QUESTION
example.com. IN A
ENTRY_END
; Query again
STEP 20 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
example.com. IN A
ENTRY_END
; Check that we get the cached SERVFAIL
STEP 30 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA SERVFAIL
SECTION QUESTION
example.com. IN A
ENTRY_END
; Wait for the SERVFAIL to expire
STEP 31 TIME_PASSES ELAPSE 6
; Query again
STEP 40 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
example.com. IN A
ENTRY_END
; Check that we got the correct answer
STEP 50 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA NOERROR
SECTION QUESTION
example.com. IN A
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
SECTION AUTHORITY
example.com. 10 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. 10 IN A 1.2.3.4
ENTRY_END
SCENARIO_END
@@ -4,7 +4,7 @@ server:
qname-minimisation: "no"
minimal-responses: no
serve-expired: yes
serve-expired-client-timeout: 1800
serve-expired-client-timeout: 1
serve-expired-reply-ttl: 123
log-servfail: yes
ede: yes
@@ -32,11 +32,11 @@ RANGE_BEGIN 0 20
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
example.com. 10 IN NS
SECTION ANSWER
example.com. IN NS ns.example.com.
example.com. 10 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ns.example.com. 10 IN A 1.2.3.4
ENTRY_END
ENTRY_BEGIN
@@ -48,14 +48,14 @@ RANGE_BEGIN 0 20
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 10 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ns.example.com. 10 IN A 1.2.3.4
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 30 100
RANGE_BEGIN 30 70
ADDRESS 1.2.3.4
; response to A query
ENTRY_BEGIN
@@ -85,13 +85,13 @@ ENTRY_BEGIN
SECTION ANSWER
example.com. 10 IN A 5.6.7.8
SECTION AUTHORITY
example.com. IN NS ns.example.com.
example.com. 10 IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ns.example.com. 10 IN A 1.2.3.4
ENTRY_END
; Wait for the TTL to expire
STEP 11 TIME_PASSES ELAPSE 3601
STEP 11 TIME_PASSES ELAPSE 11
; Query again
STEP 30 QUERY
+167
View File
@@ -0,0 +1,167 @@
; Check if an expired SERVFAIL answer stored in the global cache does not block
; ECS queries to reach the ECS cache.
server:
trust-anchor-signaling: no
target-fetch-policy: "0 0 0 0 0"
send-client-subnet: 1.2.3.4
max-client-subnet-ipv4: 21
module-config: "subnetcache iterator"
verbosity: 3
access-control: 127.0.0.1 allow_snoop
qname-minimisation: no
minimal-responses: no
serve-expired: yes
prefetch: yes
stub-zone:
name: "example.com."
stub-addr: 1.2.3.4
CONFIG_END
SCENARIO_BEGIN Test that expired SERVFAIL in global cache does not block clients to reach the ECS cache
; ns.example.com.
RANGE_BEGIN 0 10
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
; response to query of interest
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR SERVFAIL
SECTION QUESTION
www.example.com. IN A
ENTRY_END
RANGE_END
; ns.example.com.
RANGE_BEGIN 11 100
ADDRESS 1.2.3.4
ENTRY_BEGIN
MATCH opcode qtype qname
ADJUST copy_id
REPLY QR NOERROR
SECTION QUESTION
example.com. IN NS
SECTION ANSWER
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
ns.example.com. IN A 1.2.3.4
ENTRY_END
; response to query of interest
ENTRY_BEGIN
MATCH opcode qtype qname ednsdata
ADJUST copy_id copy_ednsdata_assume_clientsubnet
REPLY QR NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 10 IN A 10.20.30.40
SECTION AUTHORITY
example.com. IN NS ns.example.com.
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
; client is 127.0.0.1
00 08 ; OPC
00 05 ; option length
00 01 ; Family
08 00 ; source mask, scopemask
7f ; address
HEX_EDNSDATA_END
ns.example.com. IN A 1.2.3.4
ENTRY_END
RANGE_END
STEP 1 QUERY
ENTRY_BEGIN
REPLY RD
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; This answer should be in the global cache
STEP 2 CHECK_ANSWER
ENTRY_BEGIN
MATCH all
REPLY QR RD RA SERVFAIL
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; Bring the cached SERVFAIL to prefetch time
STEP 10 TIME_PASSES ELAPSE 5
STEP 11 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
00 08 00 05 ; OPC, optlen
00 01 08 00 ; ip4, source 8, scope 0
7f ; 127.0.0.0/8
HEX_EDNSDATA_END
ENTRY_END
; This answer was cached but a prefetch was triggerred
STEP 12 CHECK_ANSWER
ENTRY_BEGIN
MATCH opcode qtype qname
REPLY QR RD RA SERVFAIL
SECTION QUESTION
www.example.com. IN A
ENTRY_END
; Wait for the SERVFAIL to expire
STEP 13 TIME_PASSES ELAPSE 2
; Query again to verify that the record was prefetched and stored in the ECS
; cache (because the server replied with ECS this time)
STEP 14 QUERY
ENTRY_BEGIN
REPLY RD DO
SECTION QUESTION
www.example.com. IN A
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
00 08 00 05 ; OPC, optlen
00 01 08 00 ; ip4, source 8, scope 0
7f ; 127.0.0.0/8
HEX_EDNSDATA_END
ENTRY_END
; This record came from the ECS cache
STEP 15 CHECK_ANSWER
ENTRY_BEGIN
MATCH all ttl
REPLY QR RD RA DO NOERROR
SECTION QUESTION
www.example.com. IN A
SECTION ANSWER
www.example.com. 8 IN A 10.20.30.40
SECTION AUTHORITY
example.com. 3598 IN NS ns.example.com.
SECTION ADDITIONAL
HEX_EDNSDATA_BEGIN
00 08 00 05 ; OPC, optlen
00 01 08 08 ; ip4, source 8, scope 0
7f ; 127.0.0.0/8
HEX_EDNSDATA_END
ns.example.com. 3598 IN A 1.2.3.4
ENTRY_END
SCENARIO_END
+9 -24
View File
@@ -55,7 +55,6 @@
#include "util/regional.h"
#include "util/fptr_wlist.h"
#include "util/data/dname.h"
#include "util/random.h"
#include "util/rtt.h"
#include "services/cache/infra.h"
#include "sldns/wire2str.h"
@@ -88,9 +87,6 @@ struct config_parser_state* cfg_parser = 0;
/** init ports possible for use */
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);
struct config_file*
config_create(void)
{
@@ -103,6 +99,7 @@ config_create(void)
cfg->stat_interval = 0;
cfg->stat_cumulative = 0;
cfg->stat_extended = 0;
cfg->stat_inhibit_zero = 1;
cfg->num_threads = 1;
cfg->port = UNBOUND_DNS_PORT;
cfg->do_ip4 = 1;
@@ -340,6 +337,8 @@ config_create(void)
cfg->ip_ratelimit_backoff = 0;
cfg->ratelimit_backoff = 0;
cfg->outbound_msg_retry = 5;
cfg->max_sent_count = 32;
cfg->max_query_restarts = 11;
cfg->qname_minimisation = 1;
cfg->qname_minimisation_strict = 0;
cfg->shm_enable = 0;
@@ -368,10 +367,6 @@ config_create(void)
cfg->ipsecmod_whitelist = NULL;
cfg->ipsecmod_strict = 0;
#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);
#ifdef USE_CACHEDB
if(!(cfg->cachedb_backend = strdup("testframe"))) goto error_exit;
if(!(cfg->cachedb_secret = strdup("default"))) goto error_exit;
@@ -387,7 +382,6 @@ config_create(void)
cfg->ipset_name_v6 = NULL;
#endif
cfg->ede = 0;
cfg->upstream_cookies = 0;
return cfg;
error_exit:
config_delete(cfg);
@@ -525,6 +519,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_YNO("use-syslog:", use_syslog)
else S_STR("log-identity:", log_identity)
else S_YNO("extended-statistics:", stat_extended)
else S_YNO("statistics-inhibit-zero:", stat_inhibit_zero)
else S_YNO("statistics-cumulative:", stat_cumulative)
else S_YNO("shm-enable:", shm_enable)
else S_NUMBER_OR_ZERO("shm-key:", shm_key)
@@ -787,6 +782,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
else S_YNO("ip-ratelimit-backoff:", ip_ratelimit_backoff)
else S_YNO("ratelimit-backoff:", ratelimit_backoff)
else S_NUMBER_NONZERO("outbound-msg-retry:", outbound_msg_retry)
else S_NUMBER_NONZERO("max-sent-count:", max_sent_count)
else S_NUMBER_NONZERO("max-query-restarts:", max_query_restarts)
else S_SIZET_NONZERO("fast-server-num:", fast_server_num)
else S_NUMBER_OR_ZERO("fast-server-permil:", fast_server_permil)
else S_YNO("qname-minimisation:", qname_minimisation)
@@ -1005,6 +1002,7 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_DEC(opt, "statistics-interval", stat_interval)
else O_YNO(opt, "statistics-cumulative", stat_cumulative)
else O_YNO(opt, "extended-statistics", stat_extended)
else O_YNO(opt, "statistics-inhibit-zero", stat_inhibit_zero)
else O_YNO(opt, "shm-enable", shm_enable)
else O_DEC(opt, "shm-key", shm_key)
else O_YNO(opt, "use-syslog", use_syslog)
@@ -1247,6 +1245,8 @@ config_get_option(struct config_file* cfg, const char* opt,
else O_YNO(opt, "ip-ratelimit-backoff", ip_ratelimit_backoff)
else O_YNO(opt, "ratelimit-backoff", ratelimit_backoff)
else O_UNS(opt, "outbound-msg-retry", outbound_msg_retry)
else O_UNS(opt, "max-sent-count", max_sent_count)
else O_UNS(opt, "max-query-restarts", max_query_restarts)
else O_DEC(opt, "fast-server-num", fast_server_num)
else O_DEC(opt, "fast-server-permil", fast_server_permil)
else O_DEC(opt, "val-sig-skew-min", val_sig_skew_min)
@@ -1672,21 +1672,6 @@ config_delete(struct config_file* cfg)
free(cfg);
}
static void
init_cookie_secret(uint8_t* cookie_secret, size_t cookie_secret_len)
{
struct ub_randstate *rand = ub_initstate(NULL);
if (!rand)
fatal_exit("could not init random generator");
while (cookie_secret_len) {
*cookie_secret++ = (uint8_t)ub_random(rand);
cookie_secret_len--;
}
ub_randfree(rand);
}
static void
init_outgoing_availports(int* a, int num)
{
+7 -9
View File
@@ -76,6 +76,8 @@ struct config_file {
int stat_cumulative;
/** if true, the statistics are kept in greater detail */
int stat_extended;
/** if true, inhibits a lot of =0 lines from the extended stats output */
int stat_inhibit_zero;
/** number of threads to create */
int num_threads;
@@ -608,6 +610,11 @@ struct config_file {
/** number of retries on outgoing queries */
int outbound_msg_retry;
/** max sent queries per qstate; resets on query restarts (e.g.,
* CNAMES) and referrals */
int max_sent_count;
/** max number of query restarts; determines max length of CNAME chain */
int max_query_restarts;
/** minimise outgoing QNAME and hide original QTYPE if possible */
int qname_minimisation;
/** minimise QNAME in strict mode, minimise according to RFC.
@@ -690,13 +697,6 @@ struct config_file {
int redis_expire_records;
#endif
#endif
/** Downstream DNS Cookies */
/** do answer with server cookie when request contained cookie option */
int do_answer_cookie;
/** cookie secret */
uint8_t cookie_secret[40];
/** cookie secret length */
size_t cookie_secret_len;
/* ipset module */
#ifdef USE_IPSET
@@ -705,8 +705,6 @@ struct config_file {
#endif
/** respond with Extended DNS Errors (RFC8914) */
int ede;
/** Send EDNS cookies to the upstream and keep their state(RFC7873-RFC9018) */
int upstream_cookies;
};
/** from cfg username, after daemonize setup performed */
+2758 -2761
View File
File diff suppressed because it is too large Load Diff
+3 -3
View File
@@ -438,6 +438,7 @@ insecure-lan-zones{COLON} { YDVAR(1, VAR_INSECURE_LAN_ZONES) }
statistics-interval{COLON} { YDVAR(1, VAR_STATISTICS_INTERVAL) }
statistics-cumulative{COLON} { YDVAR(1, VAR_STATISTICS_CUMULATIVE) }
extended-statistics{COLON} { YDVAR(1, VAR_EXTENDED_STATISTICS) }
statistics-inhibit-zero{COLON} { YDVAR(1, VAR_STATISTICS_INHIBIT_ZERO) }
shm-enable{COLON} { YDVAR(1, VAR_SHM_ENABLE) }
shm-key{COLON} { YDVAR(1, VAR_SHM_KEY) }
remote-control{COLON} { YDVAR(0, VAR_REMOTE_CONTROL) }
@@ -514,6 +515,8 @@ ratelimit-factor{COLON} { YDVAR(1, VAR_RATELIMIT_FACTOR) }
ip-ratelimit-backoff{COLON} { YDVAR(1, VAR_IP_RATELIMIT_BACKOFF) }
ratelimit-backoff{COLON} { YDVAR(1, VAR_RATELIMIT_BACKOFF) }
outbound-msg-retry{COLON} { YDVAR(1, VAR_OUTBOUND_MSG_RETRY) }
max-sent-count{COLON} { YDVAR(1, VAR_MAX_SENT_COUNT) }
max-query-restarts{COLON} { YDVAR(1, VAR_MAX_QUERY_RESTARTS) }
low-rtt{COLON} { YDVAR(1, VAR_LOW_RTT) }
fast-server-num{COLON} { YDVAR(1, VAR_FAST_SERVER_NUM) }
low-rtt-pct{COLON} { YDVAR(1, VAR_FAST_SERVER_PERMIL) }
@@ -558,13 +561,10 @@ name-v4{COLON} { YDVAR(1, VAR_IPSET_NAME_V4) }
name-v6{COLON} { YDVAR(1, VAR_IPSET_NAME_V6) }
udp-upstream-without-downstream{COLON} { YDVAR(1, VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM) }
tcp-connection-limit{COLON} { YDVAR(2, VAR_TCP_CONNECTION_LIMIT) }
answer-cookie{COLON} { YDVAR(1, VAR_ANSWER_COOKIE ) }
cookie-secret{COLON} { YDVAR(1, VAR_COOKIE_SECRET) }
edns-client-string{COLON} { YDVAR(2, VAR_EDNS_CLIENT_STRING) }
edns-client-string-opcode{COLON} { YDVAR(1, VAR_EDNS_CLIENT_STRING_OPCODE) }
nsid{COLON} { YDVAR(1, VAR_NSID ) }
ede{COLON} { YDVAR(1, VAR_EDE ) }
upstream-cookies{COLON} { YDVAR(1, VAR_UPSTREAM_COOKIES ) }
proxy-protocol-port{COLON} { YDVAR(1, VAR_PROXY_PROTOCOL_PORT) }
<INITIAL,val>{NEWLINE} { LEXOUT(("NL\n")); cfg_parser->line++; }
+4527 -4730
View File
File diff suppressed because it is too large Load Diff
+489 -464
View File
@@ -1,14 +1,14 @@
/* A Bison parser, made by GNU Bison 2.3. */
/* A Bison parser, made by GNU Bison 3.8.2. */
/* Skeleton interface for Bison's Yacc-like parsers in C
/* Bison interface for Yacc-like parsers in C
Copyright (C) 1984, 1989, 1990, 2000, 2001, 2002, 2003, 2004, 2005, 2006
Free Software Foundation, Inc.
Copyright (C) 1984, 1989-1990, 2000-2015, 2018-2021 Free Software Foundation,
Inc.
This program is free software; you can redistribute it and/or modify
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 2, or (at your option)
any later version.
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
@@ -16,9 +16,7 @@
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, write to the Free Software
Foundation, Inc., 51 Franklin Street, Fifth Floor,
Boston, MA 02110-1301, USA. */
along with this program. If not, see <https://www.gnu.org/licenses/>. */
/* As a special exception, you may create a larger work that contains
part or all of the Bison parser skeleton and distribute that work
@@ -33,349 +31,371 @@
This special exception was added by the Free Software Foundation in
version 2.2 of Bison. */
/* Tokens. */
/* DO NOT RELY ON FEATURES THAT ARE NOT DOCUMENTED in the manual,
especially those whose name start with YY_ or yy_. They are
private implementation details that can be changed or removed. */
#ifndef YY_YY_UTIL_CONFIGPARSER_H_INCLUDED
# define YY_YY_UTIL_CONFIGPARSER_H_INCLUDED
/* Debug traces. */
#ifndef YYDEBUG
# define YYDEBUG 0
#endif
#if YYDEBUG
extern int yydebug;
#endif
/* Token kinds. */
#ifndef YYTOKENTYPE
# define YYTOKENTYPE
/* Put the tokens into the symbol table, so that GDB and other debuggers
know about them. */
enum yytokentype {
SPACE = 258,
LETTER = 259,
NEWLINE = 260,
COMMENT = 261,
COLON = 262,
ANY = 263,
ZONESTR = 264,
STRING_ARG = 265,
VAR_FORCE_TOPLEVEL = 266,
VAR_SERVER = 267,
VAR_VERBOSITY = 268,
VAR_NUM_THREADS = 269,
VAR_PORT = 270,
VAR_OUTGOING_RANGE = 271,
VAR_INTERFACE = 272,
VAR_PREFER_IP4 = 273,
VAR_DO_IP4 = 274,
VAR_DO_IP6 = 275,
VAR_PREFER_IP6 = 276,
VAR_DO_UDP = 277,
VAR_DO_TCP = 278,
VAR_TCP_MSS = 279,
VAR_OUTGOING_TCP_MSS = 280,
VAR_TCP_IDLE_TIMEOUT = 281,
VAR_EDNS_TCP_KEEPALIVE = 282,
VAR_EDNS_TCP_KEEPALIVE_TIMEOUT = 283,
VAR_CHROOT = 284,
VAR_USERNAME = 285,
VAR_DIRECTORY = 286,
VAR_LOGFILE = 287,
VAR_PIDFILE = 288,
VAR_MSG_CACHE_SIZE = 289,
VAR_MSG_CACHE_SLABS = 290,
VAR_NUM_QUERIES_PER_THREAD = 291,
VAR_RRSET_CACHE_SIZE = 292,
VAR_RRSET_CACHE_SLABS = 293,
VAR_OUTGOING_NUM_TCP = 294,
VAR_INFRA_HOST_TTL = 295,
VAR_INFRA_LAME_TTL = 296,
VAR_INFRA_CACHE_SLABS = 297,
VAR_INFRA_CACHE_NUMHOSTS = 298,
VAR_INFRA_CACHE_LAME_SIZE = 299,
VAR_NAME = 300,
VAR_STUB_ZONE = 301,
VAR_STUB_HOST = 302,
VAR_STUB_ADDR = 303,
VAR_TARGET_FETCH_POLICY = 304,
VAR_HARDEN_SHORT_BUFSIZE = 305,
VAR_HARDEN_LARGE_QUERIES = 306,
VAR_FORWARD_ZONE = 307,
VAR_FORWARD_HOST = 308,
VAR_FORWARD_ADDR = 309,
VAR_DO_NOT_QUERY_ADDRESS = 310,
VAR_HIDE_IDENTITY = 311,
VAR_HIDE_VERSION = 312,
VAR_IDENTITY = 313,
VAR_VERSION = 314,
VAR_HARDEN_GLUE = 315,
VAR_MODULE_CONF = 316,
VAR_TRUST_ANCHOR_FILE = 317,
VAR_TRUST_ANCHOR = 318,
VAR_VAL_OVERRIDE_DATE = 319,
VAR_BOGUS_TTL = 320,
VAR_VAL_CLEAN_ADDITIONAL = 321,
VAR_VAL_PERMISSIVE_MODE = 322,
VAR_INCOMING_NUM_TCP = 323,
VAR_MSG_BUFFER_SIZE = 324,
VAR_KEY_CACHE_SIZE = 325,
VAR_KEY_CACHE_SLABS = 326,
VAR_TRUSTED_KEYS_FILE = 327,
VAR_VAL_NSEC3_KEYSIZE_ITERATIONS = 328,
VAR_USE_SYSLOG = 329,
VAR_OUTGOING_INTERFACE = 330,
VAR_ROOT_HINTS = 331,
VAR_DO_NOT_QUERY_LOCALHOST = 332,
VAR_CACHE_MAX_TTL = 333,
VAR_HARDEN_DNSSEC_STRIPPED = 334,
VAR_ACCESS_CONTROL = 335,
VAR_LOCAL_ZONE = 336,
VAR_LOCAL_DATA = 337,
VAR_INTERFACE_AUTOMATIC = 338,
VAR_STATISTICS_INTERVAL = 339,
VAR_DO_DAEMONIZE = 340,
VAR_USE_CAPS_FOR_ID = 341,
VAR_STATISTICS_CUMULATIVE = 342,
VAR_OUTGOING_PORT_PERMIT = 343,
VAR_OUTGOING_PORT_AVOID = 344,
VAR_DLV_ANCHOR_FILE = 345,
VAR_DLV_ANCHOR = 346,
VAR_NEG_CACHE_SIZE = 347,
VAR_HARDEN_REFERRAL_PATH = 348,
VAR_PRIVATE_ADDRESS = 349,
VAR_PRIVATE_DOMAIN = 350,
VAR_REMOTE_CONTROL = 351,
VAR_CONTROL_ENABLE = 352,
VAR_CONTROL_INTERFACE = 353,
VAR_CONTROL_PORT = 354,
VAR_SERVER_KEY_FILE = 355,
VAR_SERVER_CERT_FILE = 356,
VAR_CONTROL_KEY_FILE = 357,
VAR_CONTROL_CERT_FILE = 358,
VAR_CONTROL_USE_CERT = 359,
VAR_TCP_REUSE_TIMEOUT = 360,
VAR_MAX_REUSE_TCP_QUERIES = 361,
VAR_EXTENDED_STATISTICS = 362,
VAR_LOCAL_DATA_PTR = 363,
VAR_JOSTLE_TIMEOUT = 364,
VAR_STUB_PRIME = 365,
VAR_UNWANTED_REPLY_THRESHOLD = 366,
VAR_LOG_TIME_ASCII = 367,
VAR_DOMAIN_INSECURE = 368,
VAR_PYTHON = 369,
VAR_PYTHON_SCRIPT = 370,
VAR_VAL_SIG_SKEW_MIN = 371,
VAR_VAL_SIG_SKEW_MAX = 372,
VAR_VAL_MAX_RESTART = 373,
VAR_CACHE_MIN_TTL = 374,
VAR_VAL_LOG_LEVEL = 375,
VAR_AUTO_TRUST_ANCHOR_FILE = 376,
VAR_KEEP_MISSING = 377,
VAR_ADD_HOLDDOWN = 378,
VAR_DEL_HOLDDOWN = 379,
VAR_SO_RCVBUF = 380,
VAR_EDNS_BUFFER_SIZE = 381,
VAR_PREFETCH = 382,
VAR_PREFETCH_KEY = 383,
VAR_SO_SNDBUF = 384,
VAR_SO_REUSEPORT = 385,
VAR_HARDEN_BELOW_NXDOMAIN = 386,
VAR_IGNORE_CD_FLAG = 387,
VAR_LOG_QUERIES = 388,
VAR_LOG_REPLIES = 389,
VAR_LOG_LOCAL_ACTIONS = 390,
VAR_TCP_UPSTREAM = 391,
VAR_SSL_UPSTREAM = 392,
VAR_TCP_AUTH_QUERY_TIMEOUT = 393,
VAR_SSL_SERVICE_KEY = 394,
VAR_SSL_SERVICE_PEM = 395,
VAR_SSL_PORT = 396,
VAR_FORWARD_FIRST = 397,
VAR_STUB_SSL_UPSTREAM = 398,
VAR_FORWARD_SSL_UPSTREAM = 399,
VAR_TLS_CERT_BUNDLE = 400,
VAR_STUB_TCP_UPSTREAM = 401,
VAR_FORWARD_TCP_UPSTREAM = 402,
VAR_HTTPS_PORT = 403,
VAR_HTTP_ENDPOINT = 404,
VAR_HTTP_MAX_STREAMS = 405,
VAR_HTTP_QUERY_BUFFER_SIZE = 406,
VAR_HTTP_RESPONSE_BUFFER_SIZE = 407,
VAR_HTTP_NODELAY = 408,
VAR_HTTP_NOTLS_DOWNSTREAM = 409,
VAR_STUB_FIRST = 410,
VAR_MINIMAL_RESPONSES = 411,
VAR_RRSET_ROUNDROBIN = 412,
VAR_MAX_UDP_SIZE = 413,
VAR_DELAY_CLOSE = 414,
VAR_UDP_CONNECT = 415,
VAR_UNBLOCK_LAN_ZONES = 416,
VAR_INSECURE_LAN_ZONES = 417,
VAR_INFRA_CACHE_MIN_RTT = 418,
VAR_INFRA_CACHE_MAX_RTT = 419,
VAR_INFRA_KEEP_PROBING = 420,
VAR_DNS64_PREFIX = 421,
VAR_DNS64_SYNTHALL = 422,
VAR_DNS64_IGNORE_AAAA = 423,
VAR_DNSTAP = 424,
VAR_DNSTAP_ENABLE = 425,
VAR_DNSTAP_SOCKET_PATH = 426,
VAR_DNSTAP_IP = 427,
VAR_DNSTAP_TLS = 428,
VAR_DNSTAP_TLS_SERVER_NAME = 429,
VAR_DNSTAP_TLS_CERT_BUNDLE = 430,
VAR_DNSTAP_TLS_CLIENT_KEY_FILE = 431,
VAR_DNSTAP_TLS_CLIENT_CERT_FILE = 432,
VAR_DNSTAP_SEND_IDENTITY = 433,
VAR_DNSTAP_SEND_VERSION = 434,
VAR_DNSTAP_BIDIRECTIONAL = 435,
VAR_DNSTAP_IDENTITY = 436,
VAR_DNSTAP_VERSION = 437,
VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES = 438,
VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES = 439,
VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES = 440,
VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES = 441,
VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES = 442,
VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES = 443,
VAR_RESPONSE_IP_TAG = 444,
VAR_RESPONSE_IP = 445,
VAR_RESPONSE_IP_DATA = 446,
VAR_HARDEN_ALGO_DOWNGRADE = 447,
VAR_IP_TRANSPARENT = 448,
VAR_IP_DSCP = 449,
VAR_DISABLE_DNSSEC_LAME_CHECK = 450,
VAR_IP_RATELIMIT = 451,
VAR_IP_RATELIMIT_SLABS = 452,
VAR_IP_RATELIMIT_SIZE = 453,
VAR_RATELIMIT = 454,
VAR_RATELIMIT_SLABS = 455,
VAR_RATELIMIT_SIZE = 456,
VAR_OUTBOUND_MSG_RETRY = 457,
VAR_RATELIMIT_FOR_DOMAIN = 458,
VAR_RATELIMIT_BELOW_DOMAIN = 459,
VAR_IP_RATELIMIT_FACTOR = 460,
VAR_RATELIMIT_FACTOR = 461,
VAR_IP_RATELIMIT_BACKOFF = 462,
VAR_RATELIMIT_BACKOFF = 463,
VAR_SEND_CLIENT_SUBNET = 464,
VAR_CLIENT_SUBNET_ZONE = 465,
VAR_CLIENT_SUBNET_ALWAYS_FORWARD = 466,
VAR_CLIENT_SUBNET_OPCODE = 467,
VAR_MAX_CLIENT_SUBNET_IPV4 = 468,
VAR_MAX_CLIENT_SUBNET_IPV6 = 469,
VAR_MIN_CLIENT_SUBNET_IPV4 = 470,
VAR_MIN_CLIENT_SUBNET_IPV6 = 471,
VAR_MAX_ECS_TREE_SIZE_IPV4 = 472,
VAR_MAX_ECS_TREE_SIZE_IPV6 = 473,
VAR_CAPS_WHITELIST = 474,
VAR_CACHE_MAX_NEGATIVE_TTL = 475,
VAR_PERMIT_SMALL_HOLDDOWN = 476,
VAR_QNAME_MINIMISATION = 477,
VAR_QNAME_MINIMISATION_STRICT = 478,
VAR_IP_FREEBIND = 479,
VAR_DEFINE_TAG = 480,
VAR_LOCAL_ZONE_TAG = 481,
VAR_ACCESS_CONTROL_TAG = 482,
VAR_LOCAL_ZONE_OVERRIDE = 483,
VAR_ACCESS_CONTROL_TAG_ACTION = 484,
VAR_ACCESS_CONTROL_TAG_DATA = 485,
VAR_VIEW = 486,
VAR_ACCESS_CONTROL_VIEW = 487,
VAR_VIEW_FIRST = 488,
VAR_SERVE_EXPIRED = 489,
VAR_SERVE_EXPIRED_TTL = 490,
VAR_SERVE_EXPIRED_TTL_RESET = 491,
VAR_SERVE_EXPIRED_REPLY_TTL = 492,
VAR_SERVE_EXPIRED_CLIENT_TIMEOUT = 493,
VAR_EDE_SERVE_EXPIRED = 494,
VAR_SERVE_ORIGINAL_TTL = 495,
VAR_FAKE_DSA = 496,
VAR_FAKE_SHA1 = 497,
VAR_LOG_IDENTITY = 498,
VAR_HIDE_TRUSTANCHOR = 499,
VAR_HIDE_HTTP_USER_AGENT = 500,
VAR_HTTP_USER_AGENT = 501,
VAR_TRUST_ANCHOR_SIGNALING = 502,
VAR_AGGRESSIVE_NSEC = 503,
VAR_USE_SYSTEMD = 504,
VAR_SHM_ENABLE = 505,
VAR_SHM_KEY = 506,
VAR_ROOT_KEY_SENTINEL = 507,
VAR_DNSCRYPT = 508,
VAR_DNSCRYPT_ENABLE = 509,
VAR_DNSCRYPT_PORT = 510,
VAR_DNSCRYPT_PROVIDER = 511,
VAR_DNSCRYPT_SECRET_KEY = 512,
VAR_DNSCRYPT_PROVIDER_CERT = 513,
VAR_DNSCRYPT_PROVIDER_CERT_ROTATED = 514,
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE = 515,
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS = 516,
VAR_DNSCRYPT_NONCE_CACHE_SIZE = 517,
VAR_DNSCRYPT_NONCE_CACHE_SLABS = 518,
VAR_PAD_RESPONSES = 519,
VAR_PAD_RESPONSES_BLOCK_SIZE = 520,
VAR_PAD_QUERIES = 521,
VAR_PAD_QUERIES_BLOCK_SIZE = 522,
VAR_IPSECMOD_ENABLED = 523,
VAR_IPSECMOD_HOOK = 524,
VAR_IPSECMOD_IGNORE_BOGUS = 525,
VAR_IPSECMOD_MAX_TTL = 526,
VAR_IPSECMOD_WHITELIST = 527,
VAR_IPSECMOD_STRICT = 528,
VAR_CACHEDB = 529,
VAR_CACHEDB_BACKEND = 530,
VAR_CACHEDB_SECRETSEED = 531,
VAR_CACHEDB_REDISHOST = 532,
VAR_CACHEDB_REDISPORT = 533,
VAR_CACHEDB_REDISTIMEOUT = 534,
VAR_CACHEDB_REDISEXPIRERECORDS = 535,
VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 536,
VAR_FOR_UPSTREAM = 537,
VAR_AUTH_ZONE = 538,
VAR_ZONEFILE = 539,
VAR_MASTER = 540,
VAR_URL = 541,
VAR_FOR_DOWNSTREAM = 542,
VAR_FALLBACK_ENABLED = 543,
VAR_TLS_ADDITIONAL_PORT = 544,
VAR_LOW_RTT = 545,
VAR_LOW_RTT_PERMIL = 546,
VAR_FAST_SERVER_PERMIL = 547,
VAR_FAST_SERVER_NUM = 548,
VAR_ALLOW_NOTIFY = 549,
VAR_TLS_WIN_CERT = 550,
VAR_TCP_CONNECTION_LIMIT = 551,
VAR_ANSWER_COOKIE = 552,
VAR_COOKIE_SECRET = 553,
VAR_FORWARD_NO_CACHE = 554,
VAR_STUB_NO_CACHE = 555,
VAR_LOG_SERVFAIL = 556,
VAR_DENY_ANY = 557,
VAR_UNKNOWN_SERVER_TIME_LIMIT = 558,
VAR_LOG_TAG_QUERYREPLY = 559,
VAR_STREAM_WAIT_SIZE = 560,
VAR_TLS_CIPHERS = 561,
VAR_TLS_CIPHERSUITES = 562,
VAR_TLS_USE_SNI = 563,
VAR_IPSET = 564,
VAR_IPSET_NAME_V4 = 565,
VAR_IPSET_NAME_V6 = 566,
VAR_TLS_SESSION_TICKET_KEYS = 567,
VAR_RPZ = 568,
VAR_TAGS = 569,
VAR_RPZ_ACTION_OVERRIDE = 570,
VAR_RPZ_CNAME_OVERRIDE = 571,
VAR_RPZ_LOG = 572,
VAR_RPZ_LOG_NAME = 573,
VAR_DYNLIB = 574,
VAR_DYNLIB_FILE = 575,
VAR_EDNS_CLIENT_STRING = 576,
VAR_EDNS_CLIENT_STRING_OPCODE = 577,
VAR_NSID = 578,
VAR_ZONEMD_PERMISSIVE_MODE = 579,
VAR_ZONEMD_CHECK = 580,
VAR_ZONEMD_REJECT_ABSENCE = 581,
VAR_RPZ_SIGNAL_NXDOMAIN_RA = 582,
VAR_INTERFACE_AUTOMATIC_PORTS = 583,
VAR_EDE = 584,
VAR_UPSTREAM_COOKIES = 585,
VAR_INTERFACE_ACTION = 586,
VAR_INTERFACE_VIEW = 587,
VAR_INTERFACE_TAG = 588,
VAR_INTERFACE_TAG_ACTION = 589,
VAR_INTERFACE_TAG_DATA = 590,
VAR_PROXY_PROTOCOL_PORT = 591
};
enum yytokentype
{
YYEMPTY = -2,
YYEOF = 0, /* "end of file" */
YYerror = 256, /* error */
YYUNDEF = 257, /* "invalid token" */
SPACE = 258, /* SPACE */
LETTER = 259, /* LETTER */
NEWLINE = 260, /* NEWLINE */
COMMENT = 261, /* COMMENT */
COLON = 262, /* COLON */
ANY = 263, /* ANY */
ZONESTR = 264, /* ZONESTR */
STRING_ARG = 265, /* STRING_ARG */
VAR_FORCE_TOPLEVEL = 266, /* VAR_FORCE_TOPLEVEL */
VAR_SERVER = 267, /* VAR_SERVER */
VAR_VERBOSITY = 268, /* VAR_VERBOSITY */
VAR_NUM_THREADS = 269, /* VAR_NUM_THREADS */
VAR_PORT = 270, /* VAR_PORT */
VAR_OUTGOING_RANGE = 271, /* VAR_OUTGOING_RANGE */
VAR_INTERFACE = 272, /* VAR_INTERFACE */
VAR_PREFER_IP4 = 273, /* VAR_PREFER_IP4 */
VAR_DO_IP4 = 274, /* VAR_DO_IP4 */
VAR_DO_IP6 = 275, /* VAR_DO_IP6 */
VAR_PREFER_IP6 = 276, /* VAR_PREFER_IP6 */
VAR_DO_UDP = 277, /* VAR_DO_UDP */
VAR_DO_TCP = 278, /* VAR_DO_TCP */
VAR_TCP_MSS = 279, /* VAR_TCP_MSS */
VAR_OUTGOING_TCP_MSS = 280, /* VAR_OUTGOING_TCP_MSS */
VAR_TCP_IDLE_TIMEOUT = 281, /* VAR_TCP_IDLE_TIMEOUT */
VAR_EDNS_TCP_KEEPALIVE = 282, /* VAR_EDNS_TCP_KEEPALIVE */
VAR_EDNS_TCP_KEEPALIVE_TIMEOUT = 283, /* VAR_EDNS_TCP_KEEPALIVE_TIMEOUT */
VAR_CHROOT = 284, /* VAR_CHROOT */
VAR_USERNAME = 285, /* VAR_USERNAME */
VAR_DIRECTORY = 286, /* VAR_DIRECTORY */
VAR_LOGFILE = 287, /* VAR_LOGFILE */
VAR_PIDFILE = 288, /* VAR_PIDFILE */
VAR_MSG_CACHE_SIZE = 289, /* VAR_MSG_CACHE_SIZE */
VAR_MSG_CACHE_SLABS = 290, /* VAR_MSG_CACHE_SLABS */
VAR_NUM_QUERIES_PER_THREAD = 291, /* VAR_NUM_QUERIES_PER_THREAD */
VAR_RRSET_CACHE_SIZE = 292, /* VAR_RRSET_CACHE_SIZE */
VAR_RRSET_CACHE_SLABS = 293, /* VAR_RRSET_CACHE_SLABS */
VAR_OUTGOING_NUM_TCP = 294, /* VAR_OUTGOING_NUM_TCP */
VAR_INFRA_HOST_TTL = 295, /* VAR_INFRA_HOST_TTL */
VAR_INFRA_LAME_TTL = 296, /* VAR_INFRA_LAME_TTL */
VAR_INFRA_CACHE_SLABS = 297, /* VAR_INFRA_CACHE_SLABS */
VAR_INFRA_CACHE_NUMHOSTS = 298, /* VAR_INFRA_CACHE_NUMHOSTS */
VAR_INFRA_CACHE_LAME_SIZE = 299, /* VAR_INFRA_CACHE_LAME_SIZE */
VAR_NAME = 300, /* VAR_NAME */
VAR_STUB_ZONE = 301, /* VAR_STUB_ZONE */
VAR_STUB_HOST = 302, /* VAR_STUB_HOST */
VAR_STUB_ADDR = 303, /* VAR_STUB_ADDR */
VAR_TARGET_FETCH_POLICY = 304, /* VAR_TARGET_FETCH_POLICY */
VAR_HARDEN_SHORT_BUFSIZE = 305, /* VAR_HARDEN_SHORT_BUFSIZE */
VAR_HARDEN_LARGE_QUERIES = 306, /* VAR_HARDEN_LARGE_QUERIES */
VAR_FORWARD_ZONE = 307, /* VAR_FORWARD_ZONE */
VAR_FORWARD_HOST = 308, /* VAR_FORWARD_HOST */
VAR_FORWARD_ADDR = 309, /* VAR_FORWARD_ADDR */
VAR_DO_NOT_QUERY_ADDRESS = 310, /* VAR_DO_NOT_QUERY_ADDRESS */
VAR_HIDE_IDENTITY = 311, /* VAR_HIDE_IDENTITY */
VAR_HIDE_VERSION = 312, /* VAR_HIDE_VERSION */
VAR_IDENTITY = 313, /* VAR_IDENTITY */
VAR_VERSION = 314, /* VAR_VERSION */
VAR_HARDEN_GLUE = 315, /* VAR_HARDEN_GLUE */
VAR_MODULE_CONF = 316, /* VAR_MODULE_CONF */
VAR_TRUST_ANCHOR_FILE = 317, /* VAR_TRUST_ANCHOR_FILE */
VAR_TRUST_ANCHOR = 318, /* VAR_TRUST_ANCHOR */
VAR_VAL_OVERRIDE_DATE = 319, /* VAR_VAL_OVERRIDE_DATE */
VAR_BOGUS_TTL = 320, /* VAR_BOGUS_TTL */
VAR_VAL_CLEAN_ADDITIONAL = 321, /* VAR_VAL_CLEAN_ADDITIONAL */
VAR_VAL_PERMISSIVE_MODE = 322, /* VAR_VAL_PERMISSIVE_MODE */
VAR_INCOMING_NUM_TCP = 323, /* VAR_INCOMING_NUM_TCP */
VAR_MSG_BUFFER_SIZE = 324, /* VAR_MSG_BUFFER_SIZE */
VAR_KEY_CACHE_SIZE = 325, /* VAR_KEY_CACHE_SIZE */
VAR_KEY_CACHE_SLABS = 326, /* VAR_KEY_CACHE_SLABS */
VAR_TRUSTED_KEYS_FILE = 327, /* VAR_TRUSTED_KEYS_FILE */
VAR_VAL_NSEC3_KEYSIZE_ITERATIONS = 328, /* VAR_VAL_NSEC3_KEYSIZE_ITERATIONS */
VAR_USE_SYSLOG = 329, /* VAR_USE_SYSLOG */
VAR_OUTGOING_INTERFACE = 330, /* VAR_OUTGOING_INTERFACE */
VAR_ROOT_HINTS = 331, /* VAR_ROOT_HINTS */
VAR_DO_NOT_QUERY_LOCALHOST = 332, /* VAR_DO_NOT_QUERY_LOCALHOST */
VAR_CACHE_MAX_TTL = 333, /* VAR_CACHE_MAX_TTL */
VAR_HARDEN_DNSSEC_STRIPPED = 334, /* VAR_HARDEN_DNSSEC_STRIPPED */
VAR_ACCESS_CONTROL = 335, /* VAR_ACCESS_CONTROL */
VAR_LOCAL_ZONE = 336, /* VAR_LOCAL_ZONE */
VAR_LOCAL_DATA = 337, /* VAR_LOCAL_DATA */
VAR_INTERFACE_AUTOMATIC = 338, /* VAR_INTERFACE_AUTOMATIC */
VAR_STATISTICS_INTERVAL = 339, /* VAR_STATISTICS_INTERVAL */
VAR_DO_DAEMONIZE = 340, /* VAR_DO_DAEMONIZE */
VAR_USE_CAPS_FOR_ID = 341, /* VAR_USE_CAPS_FOR_ID */
VAR_STATISTICS_CUMULATIVE = 342, /* VAR_STATISTICS_CUMULATIVE */
VAR_OUTGOING_PORT_PERMIT = 343, /* VAR_OUTGOING_PORT_PERMIT */
VAR_OUTGOING_PORT_AVOID = 344, /* VAR_OUTGOING_PORT_AVOID */
VAR_DLV_ANCHOR_FILE = 345, /* VAR_DLV_ANCHOR_FILE */
VAR_DLV_ANCHOR = 346, /* VAR_DLV_ANCHOR */
VAR_NEG_CACHE_SIZE = 347, /* VAR_NEG_CACHE_SIZE */
VAR_HARDEN_REFERRAL_PATH = 348, /* VAR_HARDEN_REFERRAL_PATH */
VAR_PRIVATE_ADDRESS = 349, /* VAR_PRIVATE_ADDRESS */
VAR_PRIVATE_DOMAIN = 350, /* VAR_PRIVATE_DOMAIN */
VAR_REMOTE_CONTROL = 351, /* VAR_REMOTE_CONTROL */
VAR_CONTROL_ENABLE = 352, /* VAR_CONTROL_ENABLE */
VAR_CONTROL_INTERFACE = 353, /* VAR_CONTROL_INTERFACE */
VAR_CONTROL_PORT = 354, /* VAR_CONTROL_PORT */
VAR_SERVER_KEY_FILE = 355, /* VAR_SERVER_KEY_FILE */
VAR_SERVER_CERT_FILE = 356, /* VAR_SERVER_CERT_FILE */
VAR_CONTROL_KEY_FILE = 357, /* VAR_CONTROL_KEY_FILE */
VAR_CONTROL_CERT_FILE = 358, /* VAR_CONTROL_CERT_FILE */
VAR_CONTROL_USE_CERT = 359, /* VAR_CONTROL_USE_CERT */
VAR_TCP_REUSE_TIMEOUT = 360, /* VAR_TCP_REUSE_TIMEOUT */
VAR_MAX_REUSE_TCP_QUERIES = 361, /* VAR_MAX_REUSE_TCP_QUERIES */
VAR_EXTENDED_STATISTICS = 362, /* VAR_EXTENDED_STATISTICS */
VAR_LOCAL_DATA_PTR = 363, /* VAR_LOCAL_DATA_PTR */
VAR_JOSTLE_TIMEOUT = 364, /* VAR_JOSTLE_TIMEOUT */
VAR_STUB_PRIME = 365, /* VAR_STUB_PRIME */
VAR_UNWANTED_REPLY_THRESHOLD = 366, /* VAR_UNWANTED_REPLY_THRESHOLD */
VAR_LOG_TIME_ASCII = 367, /* VAR_LOG_TIME_ASCII */
VAR_DOMAIN_INSECURE = 368, /* VAR_DOMAIN_INSECURE */
VAR_PYTHON = 369, /* VAR_PYTHON */
VAR_PYTHON_SCRIPT = 370, /* VAR_PYTHON_SCRIPT */
VAR_VAL_SIG_SKEW_MIN = 371, /* VAR_VAL_SIG_SKEW_MIN */
VAR_VAL_SIG_SKEW_MAX = 372, /* VAR_VAL_SIG_SKEW_MAX */
VAR_VAL_MAX_RESTART = 373, /* VAR_VAL_MAX_RESTART */
VAR_CACHE_MIN_TTL = 374, /* VAR_CACHE_MIN_TTL */
VAR_VAL_LOG_LEVEL = 375, /* VAR_VAL_LOG_LEVEL */
VAR_AUTO_TRUST_ANCHOR_FILE = 376, /* VAR_AUTO_TRUST_ANCHOR_FILE */
VAR_KEEP_MISSING = 377, /* VAR_KEEP_MISSING */
VAR_ADD_HOLDDOWN = 378, /* VAR_ADD_HOLDDOWN */
VAR_DEL_HOLDDOWN = 379, /* VAR_DEL_HOLDDOWN */
VAR_SO_RCVBUF = 380, /* VAR_SO_RCVBUF */
VAR_EDNS_BUFFER_SIZE = 381, /* VAR_EDNS_BUFFER_SIZE */
VAR_PREFETCH = 382, /* VAR_PREFETCH */
VAR_PREFETCH_KEY = 383, /* VAR_PREFETCH_KEY */
VAR_SO_SNDBUF = 384, /* VAR_SO_SNDBUF */
VAR_SO_REUSEPORT = 385, /* VAR_SO_REUSEPORT */
VAR_HARDEN_BELOW_NXDOMAIN = 386, /* VAR_HARDEN_BELOW_NXDOMAIN */
VAR_IGNORE_CD_FLAG = 387, /* VAR_IGNORE_CD_FLAG */
VAR_LOG_QUERIES = 388, /* VAR_LOG_QUERIES */
VAR_LOG_REPLIES = 389, /* VAR_LOG_REPLIES */
VAR_LOG_LOCAL_ACTIONS = 390, /* VAR_LOG_LOCAL_ACTIONS */
VAR_TCP_UPSTREAM = 391, /* VAR_TCP_UPSTREAM */
VAR_SSL_UPSTREAM = 392, /* VAR_SSL_UPSTREAM */
VAR_TCP_AUTH_QUERY_TIMEOUT = 393, /* VAR_TCP_AUTH_QUERY_TIMEOUT */
VAR_SSL_SERVICE_KEY = 394, /* VAR_SSL_SERVICE_KEY */
VAR_SSL_SERVICE_PEM = 395, /* VAR_SSL_SERVICE_PEM */
VAR_SSL_PORT = 396, /* VAR_SSL_PORT */
VAR_FORWARD_FIRST = 397, /* VAR_FORWARD_FIRST */
VAR_STUB_SSL_UPSTREAM = 398, /* VAR_STUB_SSL_UPSTREAM */
VAR_FORWARD_SSL_UPSTREAM = 399, /* VAR_FORWARD_SSL_UPSTREAM */
VAR_TLS_CERT_BUNDLE = 400, /* VAR_TLS_CERT_BUNDLE */
VAR_STUB_TCP_UPSTREAM = 401, /* VAR_STUB_TCP_UPSTREAM */
VAR_FORWARD_TCP_UPSTREAM = 402, /* VAR_FORWARD_TCP_UPSTREAM */
VAR_HTTPS_PORT = 403, /* VAR_HTTPS_PORT */
VAR_HTTP_ENDPOINT = 404, /* VAR_HTTP_ENDPOINT */
VAR_HTTP_MAX_STREAMS = 405, /* VAR_HTTP_MAX_STREAMS */
VAR_HTTP_QUERY_BUFFER_SIZE = 406, /* VAR_HTTP_QUERY_BUFFER_SIZE */
VAR_HTTP_RESPONSE_BUFFER_SIZE = 407, /* VAR_HTTP_RESPONSE_BUFFER_SIZE */
VAR_HTTP_NODELAY = 408, /* VAR_HTTP_NODELAY */
VAR_HTTP_NOTLS_DOWNSTREAM = 409, /* VAR_HTTP_NOTLS_DOWNSTREAM */
VAR_STUB_FIRST = 410, /* VAR_STUB_FIRST */
VAR_MINIMAL_RESPONSES = 411, /* VAR_MINIMAL_RESPONSES */
VAR_RRSET_ROUNDROBIN = 412, /* VAR_RRSET_ROUNDROBIN */
VAR_MAX_UDP_SIZE = 413, /* VAR_MAX_UDP_SIZE */
VAR_DELAY_CLOSE = 414, /* VAR_DELAY_CLOSE */
VAR_UDP_CONNECT = 415, /* VAR_UDP_CONNECT */
VAR_UNBLOCK_LAN_ZONES = 416, /* VAR_UNBLOCK_LAN_ZONES */
VAR_INSECURE_LAN_ZONES = 417, /* VAR_INSECURE_LAN_ZONES */
VAR_INFRA_CACHE_MIN_RTT = 418, /* VAR_INFRA_CACHE_MIN_RTT */
VAR_INFRA_CACHE_MAX_RTT = 419, /* VAR_INFRA_CACHE_MAX_RTT */
VAR_INFRA_KEEP_PROBING = 420, /* VAR_INFRA_KEEP_PROBING */
VAR_DNS64_PREFIX = 421, /* VAR_DNS64_PREFIX */
VAR_DNS64_SYNTHALL = 422, /* VAR_DNS64_SYNTHALL */
VAR_DNS64_IGNORE_AAAA = 423, /* VAR_DNS64_IGNORE_AAAA */
VAR_DNSTAP = 424, /* VAR_DNSTAP */
VAR_DNSTAP_ENABLE = 425, /* VAR_DNSTAP_ENABLE */
VAR_DNSTAP_SOCKET_PATH = 426, /* VAR_DNSTAP_SOCKET_PATH */
VAR_DNSTAP_IP = 427, /* VAR_DNSTAP_IP */
VAR_DNSTAP_TLS = 428, /* VAR_DNSTAP_TLS */
VAR_DNSTAP_TLS_SERVER_NAME = 429, /* VAR_DNSTAP_TLS_SERVER_NAME */
VAR_DNSTAP_TLS_CERT_BUNDLE = 430, /* VAR_DNSTAP_TLS_CERT_BUNDLE */
VAR_DNSTAP_TLS_CLIENT_KEY_FILE = 431, /* VAR_DNSTAP_TLS_CLIENT_KEY_FILE */
VAR_DNSTAP_TLS_CLIENT_CERT_FILE = 432, /* VAR_DNSTAP_TLS_CLIENT_CERT_FILE */
VAR_DNSTAP_SEND_IDENTITY = 433, /* VAR_DNSTAP_SEND_IDENTITY */
VAR_DNSTAP_SEND_VERSION = 434, /* VAR_DNSTAP_SEND_VERSION */
VAR_DNSTAP_BIDIRECTIONAL = 435, /* VAR_DNSTAP_BIDIRECTIONAL */
VAR_DNSTAP_IDENTITY = 436, /* VAR_DNSTAP_IDENTITY */
VAR_DNSTAP_VERSION = 437, /* VAR_DNSTAP_VERSION */
VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES = 438, /* VAR_DNSTAP_LOG_RESOLVER_QUERY_MESSAGES */
VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES = 439, /* VAR_DNSTAP_LOG_RESOLVER_RESPONSE_MESSAGES */
VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES = 440, /* VAR_DNSTAP_LOG_CLIENT_QUERY_MESSAGES */
VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES = 441, /* VAR_DNSTAP_LOG_CLIENT_RESPONSE_MESSAGES */
VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES = 442, /* VAR_DNSTAP_LOG_FORWARDER_QUERY_MESSAGES */
VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES = 443, /* VAR_DNSTAP_LOG_FORWARDER_RESPONSE_MESSAGES */
VAR_RESPONSE_IP_TAG = 444, /* VAR_RESPONSE_IP_TAG */
VAR_RESPONSE_IP = 445, /* VAR_RESPONSE_IP */
VAR_RESPONSE_IP_DATA = 446, /* VAR_RESPONSE_IP_DATA */
VAR_HARDEN_ALGO_DOWNGRADE = 447, /* VAR_HARDEN_ALGO_DOWNGRADE */
VAR_IP_TRANSPARENT = 448, /* VAR_IP_TRANSPARENT */
VAR_IP_DSCP = 449, /* VAR_IP_DSCP */
VAR_DISABLE_DNSSEC_LAME_CHECK = 450, /* VAR_DISABLE_DNSSEC_LAME_CHECK */
VAR_IP_RATELIMIT = 451, /* VAR_IP_RATELIMIT */
VAR_IP_RATELIMIT_SLABS = 452, /* VAR_IP_RATELIMIT_SLABS */
VAR_IP_RATELIMIT_SIZE = 453, /* VAR_IP_RATELIMIT_SIZE */
VAR_RATELIMIT = 454, /* VAR_RATELIMIT */
VAR_RATELIMIT_SLABS = 455, /* VAR_RATELIMIT_SLABS */
VAR_RATELIMIT_SIZE = 456, /* VAR_RATELIMIT_SIZE */
VAR_OUTBOUND_MSG_RETRY = 457, /* VAR_OUTBOUND_MSG_RETRY */
VAR_MAX_SENT_COUNT = 458, /* VAR_MAX_SENT_COUNT */
VAR_MAX_QUERY_RESTARTS = 459, /* VAR_MAX_QUERY_RESTARTS */
VAR_RATELIMIT_FOR_DOMAIN = 460, /* VAR_RATELIMIT_FOR_DOMAIN */
VAR_RATELIMIT_BELOW_DOMAIN = 461, /* VAR_RATELIMIT_BELOW_DOMAIN */
VAR_IP_RATELIMIT_FACTOR = 462, /* VAR_IP_RATELIMIT_FACTOR */
VAR_RATELIMIT_FACTOR = 463, /* VAR_RATELIMIT_FACTOR */
VAR_IP_RATELIMIT_BACKOFF = 464, /* VAR_IP_RATELIMIT_BACKOFF */
VAR_RATELIMIT_BACKOFF = 465, /* VAR_RATELIMIT_BACKOFF */
VAR_SEND_CLIENT_SUBNET = 466, /* VAR_SEND_CLIENT_SUBNET */
VAR_CLIENT_SUBNET_ZONE = 467, /* VAR_CLIENT_SUBNET_ZONE */
VAR_CLIENT_SUBNET_ALWAYS_FORWARD = 468, /* VAR_CLIENT_SUBNET_ALWAYS_FORWARD */
VAR_CLIENT_SUBNET_OPCODE = 469, /* VAR_CLIENT_SUBNET_OPCODE */
VAR_MAX_CLIENT_SUBNET_IPV4 = 470, /* VAR_MAX_CLIENT_SUBNET_IPV4 */
VAR_MAX_CLIENT_SUBNET_IPV6 = 471, /* VAR_MAX_CLIENT_SUBNET_IPV6 */
VAR_MIN_CLIENT_SUBNET_IPV4 = 472, /* VAR_MIN_CLIENT_SUBNET_IPV4 */
VAR_MIN_CLIENT_SUBNET_IPV6 = 473, /* VAR_MIN_CLIENT_SUBNET_IPV6 */
VAR_MAX_ECS_TREE_SIZE_IPV4 = 474, /* VAR_MAX_ECS_TREE_SIZE_IPV4 */
VAR_MAX_ECS_TREE_SIZE_IPV6 = 475, /* VAR_MAX_ECS_TREE_SIZE_IPV6 */
VAR_CAPS_WHITELIST = 476, /* VAR_CAPS_WHITELIST */
VAR_CACHE_MAX_NEGATIVE_TTL = 477, /* VAR_CACHE_MAX_NEGATIVE_TTL */
VAR_PERMIT_SMALL_HOLDDOWN = 478, /* VAR_PERMIT_SMALL_HOLDDOWN */
VAR_QNAME_MINIMISATION = 479, /* VAR_QNAME_MINIMISATION */
VAR_QNAME_MINIMISATION_STRICT = 480, /* VAR_QNAME_MINIMISATION_STRICT */
VAR_IP_FREEBIND = 481, /* VAR_IP_FREEBIND */
VAR_DEFINE_TAG = 482, /* VAR_DEFINE_TAG */
VAR_LOCAL_ZONE_TAG = 483, /* VAR_LOCAL_ZONE_TAG */
VAR_ACCESS_CONTROL_TAG = 484, /* VAR_ACCESS_CONTROL_TAG */
VAR_LOCAL_ZONE_OVERRIDE = 485, /* VAR_LOCAL_ZONE_OVERRIDE */
VAR_ACCESS_CONTROL_TAG_ACTION = 486, /* VAR_ACCESS_CONTROL_TAG_ACTION */
VAR_ACCESS_CONTROL_TAG_DATA = 487, /* VAR_ACCESS_CONTROL_TAG_DATA */
VAR_VIEW = 488, /* VAR_VIEW */
VAR_ACCESS_CONTROL_VIEW = 489, /* VAR_ACCESS_CONTROL_VIEW */
VAR_VIEW_FIRST = 490, /* VAR_VIEW_FIRST */
VAR_SERVE_EXPIRED = 491, /* VAR_SERVE_EXPIRED */
VAR_SERVE_EXPIRED_TTL = 492, /* VAR_SERVE_EXPIRED_TTL */
VAR_SERVE_EXPIRED_TTL_RESET = 493, /* VAR_SERVE_EXPIRED_TTL_RESET */
VAR_SERVE_EXPIRED_REPLY_TTL = 494, /* VAR_SERVE_EXPIRED_REPLY_TTL */
VAR_SERVE_EXPIRED_CLIENT_TIMEOUT = 495, /* VAR_SERVE_EXPIRED_CLIENT_TIMEOUT */
VAR_EDE_SERVE_EXPIRED = 496, /* VAR_EDE_SERVE_EXPIRED */
VAR_SERVE_ORIGINAL_TTL = 497, /* VAR_SERVE_ORIGINAL_TTL */
VAR_FAKE_DSA = 498, /* VAR_FAKE_DSA */
VAR_FAKE_SHA1 = 499, /* VAR_FAKE_SHA1 */
VAR_LOG_IDENTITY = 500, /* VAR_LOG_IDENTITY */
VAR_HIDE_TRUSTANCHOR = 501, /* VAR_HIDE_TRUSTANCHOR */
VAR_HIDE_HTTP_USER_AGENT = 502, /* VAR_HIDE_HTTP_USER_AGENT */
VAR_HTTP_USER_AGENT = 503, /* VAR_HTTP_USER_AGENT */
VAR_TRUST_ANCHOR_SIGNALING = 504, /* VAR_TRUST_ANCHOR_SIGNALING */
VAR_AGGRESSIVE_NSEC = 505, /* VAR_AGGRESSIVE_NSEC */
VAR_USE_SYSTEMD = 506, /* VAR_USE_SYSTEMD */
VAR_SHM_ENABLE = 507, /* VAR_SHM_ENABLE */
VAR_SHM_KEY = 508, /* VAR_SHM_KEY */
VAR_ROOT_KEY_SENTINEL = 509, /* VAR_ROOT_KEY_SENTINEL */
VAR_DNSCRYPT = 510, /* VAR_DNSCRYPT */
VAR_DNSCRYPT_ENABLE = 511, /* VAR_DNSCRYPT_ENABLE */
VAR_DNSCRYPT_PORT = 512, /* VAR_DNSCRYPT_PORT */
VAR_DNSCRYPT_PROVIDER = 513, /* VAR_DNSCRYPT_PROVIDER */
VAR_DNSCRYPT_SECRET_KEY = 514, /* VAR_DNSCRYPT_SECRET_KEY */
VAR_DNSCRYPT_PROVIDER_CERT = 515, /* VAR_DNSCRYPT_PROVIDER_CERT */
VAR_DNSCRYPT_PROVIDER_CERT_ROTATED = 516, /* VAR_DNSCRYPT_PROVIDER_CERT_ROTATED */
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE = 517, /* VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE */
VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS = 518, /* VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS */
VAR_DNSCRYPT_NONCE_CACHE_SIZE = 519, /* VAR_DNSCRYPT_NONCE_CACHE_SIZE */
VAR_DNSCRYPT_NONCE_CACHE_SLABS = 520, /* VAR_DNSCRYPT_NONCE_CACHE_SLABS */
VAR_PAD_RESPONSES = 521, /* VAR_PAD_RESPONSES */
VAR_PAD_RESPONSES_BLOCK_SIZE = 522, /* VAR_PAD_RESPONSES_BLOCK_SIZE */
VAR_PAD_QUERIES = 523, /* VAR_PAD_QUERIES */
VAR_PAD_QUERIES_BLOCK_SIZE = 524, /* VAR_PAD_QUERIES_BLOCK_SIZE */
VAR_IPSECMOD_ENABLED = 525, /* VAR_IPSECMOD_ENABLED */
VAR_IPSECMOD_HOOK = 526, /* VAR_IPSECMOD_HOOK */
VAR_IPSECMOD_IGNORE_BOGUS = 527, /* VAR_IPSECMOD_IGNORE_BOGUS */
VAR_IPSECMOD_MAX_TTL = 528, /* VAR_IPSECMOD_MAX_TTL */
VAR_IPSECMOD_WHITELIST = 529, /* VAR_IPSECMOD_WHITELIST */
VAR_IPSECMOD_STRICT = 530, /* VAR_IPSECMOD_STRICT */
VAR_CACHEDB = 531, /* VAR_CACHEDB */
VAR_CACHEDB_BACKEND = 532, /* VAR_CACHEDB_BACKEND */
VAR_CACHEDB_SECRETSEED = 533, /* VAR_CACHEDB_SECRETSEED */
VAR_CACHEDB_REDISHOST = 534, /* VAR_CACHEDB_REDISHOST */
VAR_CACHEDB_REDISPORT = 535, /* VAR_CACHEDB_REDISPORT */
VAR_CACHEDB_REDISTIMEOUT = 536, /* VAR_CACHEDB_REDISTIMEOUT */
VAR_CACHEDB_REDISEXPIRERECORDS = 537, /* VAR_CACHEDB_REDISEXPIRERECORDS */
VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM = 538, /* VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM */
VAR_FOR_UPSTREAM = 539, /* VAR_FOR_UPSTREAM */
VAR_AUTH_ZONE = 540, /* VAR_AUTH_ZONE */
VAR_ZONEFILE = 541, /* VAR_ZONEFILE */
VAR_MASTER = 542, /* VAR_MASTER */
VAR_URL = 543, /* VAR_URL */
VAR_FOR_DOWNSTREAM = 544, /* VAR_FOR_DOWNSTREAM */
VAR_FALLBACK_ENABLED = 545, /* VAR_FALLBACK_ENABLED */
VAR_TLS_ADDITIONAL_PORT = 546, /* VAR_TLS_ADDITIONAL_PORT */
VAR_LOW_RTT = 547, /* VAR_LOW_RTT */
VAR_LOW_RTT_PERMIL = 548, /* VAR_LOW_RTT_PERMIL */
VAR_FAST_SERVER_PERMIL = 549, /* VAR_FAST_SERVER_PERMIL */
VAR_FAST_SERVER_NUM = 550, /* VAR_FAST_SERVER_NUM */
VAR_ALLOW_NOTIFY = 551, /* VAR_ALLOW_NOTIFY */
VAR_TLS_WIN_CERT = 552, /* VAR_TLS_WIN_CERT */
VAR_TCP_CONNECTION_LIMIT = 553, /* VAR_TCP_CONNECTION_LIMIT */
VAR_FORWARD_NO_CACHE = 554, /* VAR_FORWARD_NO_CACHE */
VAR_STUB_NO_CACHE = 555, /* VAR_STUB_NO_CACHE */
VAR_LOG_SERVFAIL = 556, /* VAR_LOG_SERVFAIL */
VAR_DENY_ANY = 557, /* VAR_DENY_ANY */
VAR_UNKNOWN_SERVER_TIME_LIMIT = 558, /* VAR_UNKNOWN_SERVER_TIME_LIMIT */
VAR_LOG_TAG_QUERYREPLY = 559, /* VAR_LOG_TAG_QUERYREPLY */
VAR_STREAM_WAIT_SIZE = 560, /* VAR_STREAM_WAIT_SIZE */
VAR_TLS_CIPHERS = 561, /* VAR_TLS_CIPHERS */
VAR_TLS_CIPHERSUITES = 562, /* VAR_TLS_CIPHERSUITES */
VAR_TLS_USE_SNI = 563, /* VAR_TLS_USE_SNI */
VAR_IPSET = 564, /* VAR_IPSET */
VAR_IPSET_NAME_V4 = 565, /* VAR_IPSET_NAME_V4 */
VAR_IPSET_NAME_V6 = 566, /* VAR_IPSET_NAME_V6 */
VAR_TLS_SESSION_TICKET_KEYS = 567, /* VAR_TLS_SESSION_TICKET_KEYS */
VAR_RPZ = 568, /* VAR_RPZ */
VAR_TAGS = 569, /* VAR_TAGS */
VAR_RPZ_ACTION_OVERRIDE = 570, /* VAR_RPZ_ACTION_OVERRIDE */
VAR_RPZ_CNAME_OVERRIDE = 571, /* VAR_RPZ_CNAME_OVERRIDE */
VAR_RPZ_LOG = 572, /* VAR_RPZ_LOG */
VAR_RPZ_LOG_NAME = 573, /* VAR_RPZ_LOG_NAME */
VAR_DYNLIB = 574, /* VAR_DYNLIB */
VAR_DYNLIB_FILE = 575, /* VAR_DYNLIB_FILE */
VAR_EDNS_CLIENT_STRING = 576, /* VAR_EDNS_CLIENT_STRING */
VAR_EDNS_CLIENT_STRING_OPCODE = 577, /* VAR_EDNS_CLIENT_STRING_OPCODE */
VAR_NSID = 578, /* VAR_NSID */
VAR_ZONEMD_PERMISSIVE_MODE = 579, /* VAR_ZONEMD_PERMISSIVE_MODE */
VAR_ZONEMD_CHECK = 580, /* VAR_ZONEMD_CHECK */
VAR_ZONEMD_REJECT_ABSENCE = 581, /* VAR_ZONEMD_REJECT_ABSENCE */
VAR_RPZ_SIGNAL_NXDOMAIN_RA = 582, /* VAR_RPZ_SIGNAL_NXDOMAIN_RA */
VAR_INTERFACE_AUTOMATIC_PORTS = 583, /* VAR_INTERFACE_AUTOMATIC_PORTS */
VAR_EDE = 584, /* VAR_EDE */
VAR_INTERFACE_ACTION = 585, /* VAR_INTERFACE_ACTION */
VAR_INTERFACE_VIEW = 586, /* VAR_INTERFACE_VIEW */
VAR_INTERFACE_TAG = 587, /* VAR_INTERFACE_TAG */
VAR_INTERFACE_TAG_ACTION = 588, /* VAR_INTERFACE_TAG_ACTION */
VAR_INTERFACE_TAG_DATA = 589, /* VAR_INTERFACE_TAG_DATA */
VAR_PROXY_PROTOCOL_PORT = 590, /* VAR_PROXY_PROTOCOL_PORT */
VAR_STATISTICS_INHIBIT_ZERO = 591 /* VAR_STATISTICS_INHIBIT_ZERO */
};
typedef enum yytokentype yytoken_kind_t;
#endif
/* Tokens. */
/* Token kinds. */
#define YYEMPTY -2
#define YYEOF 0
#define YYerror 256
#define YYUNDEF 257
#define SPACE 258
#define LETTER 259
#define NEWLINE 260
@@ -576,102 +596,102 @@
#define VAR_RATELIMIT_SLABS 455
#define VAR_RATELIMIT_SIZE 456
#define VAR_OUTBOUND_MSG_RETRY 457
#define VAR_RATELIMIT_FOR_DOMAIN 458
#define VAR_RATELIMIT_BELOW_DOMAIN 459
#define VAR_IP_RATELIMIT_FACTOR 460
#define VAR_RATELIMIT_FACTOR 461
#define VAR_IP_RATELIMIT_BACKOFF 462
#define VAR_RATELIMIT_BACKOFF 463
#define VAR_SEND_CLIENT_SUBNET 464
#define VAR_CLIENT_SUBNET_ZONE 465
#define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 466
#define VAR_CLIENT_SUBNET_OPCODE 467
#define VAR_MAX_CLIENT_SUBNET_IPV4 468
#define VAR_MAX_CLIENT_SUBNET_IPV6 469
#define VAR_MIN_CLIENT_SUBNET_IPV4 470
#define VAR_MIN_CLIENT_SUBNET_IPV6 471
#define VAR_MAX_ECS_TREE_SIZE_IPV4 472
#define VAR_MAX_ECS_TREE_SIZE_IPV6 473
#define VAR_CAPS_WHITELIST 474
#define VAR_CACHE_MAX_NEGATIVE_TTL 475
#define VAR_PERMIT_SMALL_HOLDDOWN 476
#define VAR_QNAME_MINIMISATION 477
#define VAR_QNAME_MINIMISATION_STRICT 478
#define VAR_IP_FREEBIND 479
#define VAR_DEFINE_TAG 480
#define VAR_LOCAL_ZONE_TAG 481
#define VAR_ACCESS_CONTROL_TAG 482
#define VAR_LOCAL_ZONE_OVERRIDE 483
#define VAR_ACCESS_CONTROL_TAG_ACTION 484
#define VAR_ACCESS_CONTROL_TAG_DATA 485
#define VAR_VIEW 486
#define VAR_ACCESS_CONTROL_VIEW 487
#define VAR_VIEW_FIRST 488
#define VAR_SERVE_EXPIRED 489
#define VAR_SERVE_EXPIRED_TTL 490
#define VAR_SERVE_EXPIRED_TTL_RESET 491
#define VAR_SERVE_EXPIRED_REPLY_TTL 492
#define VAR_SERVE_EXPIRED_CLIENT_TIMEOUT 493
#define VAR_EDE_SERVE_EXPIRED 494
#define VAR_SERVE_ORIGINAL_TTL 495
#define VAR_FAKE_DSA 496
#define VAR_FAKE_SHA1 497
#define VAR_LOG_IDENTITY 498
#define VAR_HIDE_TRUSTANCHOR 499
#define VAR_HIDE_HTTP_USER_AGENT 500
#define VAR_HTTP_USER_AGENT 501
#define VAR_TRUST_ANCHOR_SIGNALING 502
#define VAR_AGGRESSIVE_NSEC 503
#define VAR_USE_SYSTEMD 504
#define VAR_SHM_ENABLE 505
#define VAR_SHM_KEY 506
#define VAR_ROOT_KEY_SENTINEL 507
#define VAR_DNSCRYPT 508
#define VAR_DNSCRYPT_ENABLE 509
#define VAR_DNSCRYPT_PORT 510
#define VAR_DNSCRYPT_PROVIDER 511
#define VAR_DNSCRYPT_SECRET_KEY 512
#define VAR_DNSCRYPT_PROVIDER_CERT 513
#define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 514
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 515
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 516
#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 517
#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 518
#define VAR_PAD_RESPONSES 519
#define VAR_PAD_RESPONSES_BLOCK_SIZE 520
#define VAR_PAD_QUERIES 521
#define VAR_PAD_QUERIES_BLOCK_SIZE 522
#define VAR_IPSECMOD_ENABLED 523
#define VAR_IPSECMOD_HOOK 524
#define VAR_IPSECMOD_IGNORE_BOGUS 525
#define VAR_IPSECMOD_MAX_TTL 526
#define VAR_IPSECMOD_WHITELIST 527
#define VAR_IPSECMOD_STRICT 528
#define VAR_CACHEDB 529
#define VAR_CACHEDB_BACKEND 530
#define VAR_CACHEDB_SECRETSEED 531
#define VAR_CACHEDB_REDISHOST 532
#define VAR_CACHEDB_REDISPORT 533
#define VAR_CACHEDB_REDISTIMEOUT 534
#define VAR_CACHEDB_REDISEXPIRERECORDS 535
#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 536
#define VAR_FOR_UPSTREAM 537
#define VAR_AUTH_ZONE 538
#define VAR_ZONEFILE 539
#define VAR_MASTER 540
#define VAR_URL 541
#define VAR_FOR_DOWNSTREAM 542
#define VAR_FALLBACK_ENABLED 543
#define VAR_TLS_ADDITIONAL_PORT 544
#define VAR_LOW_RTT 545
#define VAR_LOW_RTT_PERMIL 546
#define VAR_FAST_SERVER_PERMIL 547
#define VAR_FAST_SERVER_NUM 548
#define VAR_ALLOW_NOTIFY 549
#define VAR_TLS_WIN_CERT 550
#define VAR_TCP_CONNECTION_LIMIT 551
#define VAR_ANSWER_COOKIE 552
#define VAR_COOKIE_SECRET 553
#define VAR_MAX_SENT_COUNT 458
#define VAR_MAX_QUERY_RESTARTS 459
#define VAR_RATELIMIT_FOR_DOMAIN 460
#define VAR_RATELIMIT_BELOW_DOMAIN 461
#define VAR_IP_RATELIMIT_FACTOR 462
#define VAR_RATELIMIT_FACTOR 463
#define VAR_IP_RATELIMIT_BACKOFF 464
#define VAR_RATELIMIT_BACKOFF 465
#define VAR_SEND_CLIENT_SUBNET 466
#define VAR_CLIENT_SUBNET_ZONE 467
#define VAR_CLIENT_SUBNET_ALWAYS_FORWARD 468
#define VAR_CLIENT_SUBNET_OPCODE 469
#define VAR_MAX_CLIENT_SUBNET_IPV4 470
#define VAR_MAX_CLIENT_SUBNET_IPV6 471
#define VAR_MIN_CLIENT_SUBNET_IPV4 472
#define VAR_MIN_CLIENT_SUBNET_IPV6 473
#define VAR_MAX_ECS_TREE_SIZE_IPV4 474
#define VAR_MAX_ECS_TREE_SIZE_IPV6 475
#define VAR_CAPS_WHITELIST 476
#define VAR_CACHE_MAX_NEGATIVE_TTL 477
#define VAR_PERMIT_SMALL_HOLDDOWN 478
#define VAR_QNAME_MINIMISATION 479
#define VAR_QNAME_MINIMISATION_STRICT 480
#define VAR_IP_FREEBIND 481
#define VAR_DEFINE_TAG 482
#define VAR_LOCAL_ZONE_TAG 483
#define VAR_ACCESS_CONTROL_TAG 484
#define VAR_LOCAL_ZONE_OVERRIDE 485
#define VAR_ACCESS_CONTROL_TAG_ACTION 486
#define VAR_ACCESS_CONTROL_TAG_DATA 487
#define VAR_VIEW 488
#define VAR_ACCESS_CONTROL_VIEW 489
#define VAR_VIEW_FIRST 490
#define VAR_SERVE_EXPIRED 491
#define VAR_SERVE_EXPIRED_TTL 492
#define VAR_SERVE_EXPIRED_TTL_RESET 493
#define VAR_SERVE_EXPIRED_REPLY_TTL 494
#define VAR_SERVE_EXPIRED_CLIENT_TIMEOUT 495
#define VAR_EDE_SERVE_EXPIRED 496
#define VAR_SERVE_ORIGINAL_TTL 497
#define VAR_FAKE_DSA 498
#define VAR_FAKE_SHA1 499
#define VAR_LOG_IDENTITY 500
#define VAR_HIDE_TRUSTANCHOR 501
#define VAR_HIDE_HTTP_USER_AGENT 502
#define VAR_HTTP_USER_AGENT 503
#define VAR_TRUST_ANCHOR_SIGNALING 504
#define VAR_AGGRESSIVE_NSEC 505
#define VAR_USE_SYSTEMD 506
#define VAR_SHM_ENABLE 507
#define VAR_SHM_KEY 508
#define VAR_ROOT_KEY_SENTINEL 509
#define VAR_DNSCRYPT 510
#define VAR_DNSCRYPT_ENABLE 511
#define VAR_DNSCRYPT_PORT 512
#define VAR_DNSCRYPT_PROVIDER 513
#define VAR_DNSCRYPT_SECRET_KEY 514
#define VAR_DNSCRYPT_PROVIDER_CERT 515
#define VAR_DNSCRYPT_PROVIDER_CERT_ROTATED 516
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SIZE 517
#define VAR_DNSCRYPT_SHARED_SECRET_CACHE_SLABS 518
#define VAR_DNSCRYPT_NONCE_CACHE_SIZE 519
#define VAR_DNSCRYPT_NONCE_CACHE_SLABS 520
#define VAR_PAD_RESPONSES 521
#define VAR_PAD_RESPONSES_BLOCK_SIZE 522
#define VAR_PAD_QUERIES 523
#define VAR_PAD_QUERIES_BLOCK_SIZE 524
#define VAR_IPSECMOD_ENABLED 525
#define VAR_IPSECMOD_HOOK 526
#define VAR_IPSECMOD_IGNORE_BOGUS 527
#define VAR_IPSECMOD_MAX_TTL 528
#define VAR_IPSECMOD_WHITELIST 529
#define VAR_IPSECMOD_STRICT 530
#define VAR_CACHEDB 531
#define VAR_CACHEDB_BACKEND 532
#define VAR_CACHEDB_SECRETSEED 533
#define VAR_CACHEDB_REDISHOST 534
#define VAR_CACHEDB_REDISPORT 535
#define VAR_CACHEDB_REDISTIMEOUT 536
#define VAR_CACHEDB_REDISEXPIRERECORDS 537
#define VAR_UDP_UPSTREAM_WITHOUT_DOWNSTREAM 538
#define VAR_FOR_UPSTREAM 539
#define VAR_AUTH_ZONE 540
#define VAR_ZONEFILE 541
#define VAR_MASTER 542
#define VAR_URL 543
#define VAR_FOR_DOWNSTREAM 544
#define VAR_FALLBACK_ENABLED 545
#define VAR_TLS_ADDITIONAL_PORT 546
#define VAR_LOW_RTT 547
#define VAR_LOW_RTT_PERMIL 548
#define VAR_FAST_SERVER_PERMIL 549
#define VAR_FAST_SERVER_NUM 550
#define VAR_ALLOW_NOTIFY 551
#define VAR_TLS_WIN_CERT 552
#define VAR_TCP_CONNECTION_LIMIT 553
#define VAR_FORWARD_NO_CACHE 554
#define VAR_STUB_NO_CACHE 555
#define VAR_LOG_SERVFAIL 556
@@ -703,30 +723,35 @@
#define VAR_RPZ_SIGNAL_NXDOMAIN_RA 582
#define VAR_INTERFACE_AUTOMATIC_PORTS 583
#define VAR_EDE 584
#define VAR_UPSTREAM_COOKIES 585
#define VAR_INTERFACE_ACTION 586
#define VAR_INTERFACE_VIEW 587
#define VAR_INTERFACE_TAG 588
#define VAR_INTERFACE_TAG_ACTION 589
#define VAR_INTERFACE_TAG_DATA 590
#define VAR_PROXY_PROTOCOL_PORT 591
#define VAR_INTERFACE_ACTION 585
#define VAR_INTERFACE_VIEW 586
#define VAR_INTERFACE_TAG 587
#define VAR_INTERFACE_TAG_ACTION 588
#define VAR_INTERFACE_TAG_DATA 589
#define VAR_PROXY_PROTOCOL_PORT 590
#define VAR_STATISTICS_INHIBIT_ZERO 591
/* Value type. */
#if ! defined YYSTYPE && ! defined YYSTYPE_IS_DECLARED
typedef union YYSTYPE
#line 69 "./util/configparser.y"
union YYSTYPE
{
#line 67 "./util/configparser.y"
char* str;
}
/* Line 1529 of yacc.c. */
#line 725 "util/configparser.h"
YYSTYPE;
# define yystype YYSTYPE /* obsolescent; will be withdrawn */
# define YYSTYPE_IS_DECLARED 1
#line 743 "util/configparser.h"
};
typedef union YYSTYPE YYSTYPE;
# define YYSTYPE_IS_TRIVIAL 1
# define YYSTYPE_IS_DECLARED 1
#endif
extern YYSTYPE yylval;
int yyparse (void);
#endif /* !YY_YY_UTIL_CONFIGPARSER_H_INCLUDED */
+35 -45
View File
@@ -42,13 +42,11 @@
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <time.h>
#include <assert.h>
#include "util/configyyrename.h"
#include "util/config_file.h"
#include "util/net_help.h"
#include "sldns/str2wire.h"
int ub_c_lex(void);
void ub_c_error(const char *message);
@@ -142,7 +140,7 @@ extern struct config_parser_state* cfg_parser;
%token VAR_DISABLE_DNSSEC_LAME_CHECK
%token VAR_IP_RATELIMIT VAR_IP_RATELIMIT_SLABS VAR_IP_RATELIMIT_SIZE
%token VAR_RATELIMIT VAR_RATELIMIT_SLABS VAR_RATELIMIT_SIZE
%token VAR_OUTBOUND_MSG_RETRY
%token VAR_OUTBOUND_MSG_RETRY VAR_MAX_SENT_COUNT VAR_MAX_QUERY_RESTARTS
%token VAR_RATELIMIT_FOR_DOMAIN VAR_RATELIMIT_BELOW_DOMAIN
%token VAR_IP_RATELIMIT_FACTOR VAR_RATELIMIT_FACTOR
%token VAR_IP_RATELIMIT_BACKOFF VAR_RATELIMIT_BACKOFF
@@ -183,7 +181,6 @@ extern struct config_parser_state* cfg_parser;
%token VAR_FALLBACK_ENABLED VAR_TLS_ADDITIONAL_PORT VAR_LOW_RTT VAR_LOW_RTT_PERMIL
%token VAR_FAST_SERVER_PERMIL VAR_FAST_SERVER_NUM
%token VAR_ALLOW_NOTIFY VAR_TLS_WIN_CERT VAR_TCP_CONNECTION_LIMIT
%token VAR_ANSWER_COOKIE VAR_COOKIE_SECRET
%token VAR_FORWARD_NO_CACHE VAR_STUB_NO_CACHE VAR_LOG_SERVFAIL VAR_DENY_ANY
%token VAR_UNKNOWN_SERVER_TIME_LIMIT VAR_LOG_TAG_QUERYREPLY
%token VAR_STREAM_WAIT_SIZE VAR_TLS_CIPHERS VAR_TLS_CIPHERSUITES VAR_TLS_USE_SNI
@@ -194,10 +191,9 @@ extern struct config_parser_state* cfg_parser;
%token VAR_EDNS_CLIENT_STRING_OPCODE VAR_NSID
%token VAR_ZONEMD_PERMISSIVE_MODE VAR_ZONEMD_CHECK VAR_ZONEMD_REJECT_ABSENCE
%token VAR_RPZ_SIGNAL_NXDOMAIN_RA VAR_INTERFACE_AUTOMATIC_PORTS VAR_EDE
%token VAR_UPSTREAM_COOKIES
%token VAR_INTERFACE_ACTION VAR_INTERFACE_VIEW VAR_INTERFACE_TAG
%token VAR_INTERFACE_TAG_ACTION VAR_INTERFACE_TAG_DATA
%token VAR_PROXY_PROTOCOL_PORT
%token VAR_PROXY_PROTOCOL_PORT VAR_STATISTICS_INHIBIT_ZERO
%%
toplevelvars: /* empty */ | toplevelvars toplevelvar ;
@@ -286,6 +282,7 @@ content_server: server_num_threads | server_verbosity | server_port |
server_ratelimit_below_domain | server_ratelimit_factor |
server_ip_ratelimit_factor | server_ratelimit_backoff |
server_ip_ratelimit_backoff | server_outbound_msg_retry |
server_max_sent_count | server_max_query_restarts |
server_send_client_subnet | server_client_subnet_zone |
server_client_subnet_always_forward | server_client_subnet_opcode |
server_max_client_subnet_ipv4 | server_max_client_subnet_ipv6 |
@@ -321,13 +318,12 @@ content_server: server_num_threads | server_verbosity | server_port |
server_unknown_server_time_limit | server_log_tag_queryreply |
server_stream_wait_size | server_tls_ciphers |
server_tls_ciphersuites | server_tls_session_ticket_keys |
server_answer_cookie | server_cookie_secret |
server_tls_use_sni | server_edns_client_string |
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 |
server_interface_automatic_ports | server_ede | server_upstream_cookies |
server_proxy_protocol_port
server_interface_automatic_ports | server_ede |
server_proxy_protocol_port | server_statistics_inhibit_zero
;
stubstart: VAR_STUB_ZONE
{
@@ -559,6 +555,15 @@ server_extended_statistics: VAR_EXTENDED_STATISTICS STRING_ARG
free($2);
}
;
server_statistics_inhibit_zero: VAR_STATISTICS_INHIBIT_ZERO STRING_ARG
{
OUTYY(("P(server_statistics_inhibit_zero:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->stat_inhibit_zero = (strcmp($2, "yes")==0);
free($2);
}
;
server_shm_enable: VAR_SHM_ENABLE STRING_ARG
{
OUTYY(("P(server_shm_enable:%s)\n", $2));
@@ -2641,6 +2646,24 @@ server_outbound_msg_retry: VAR_OUTBOUND_MSG_RETRY STRING_ARG
free($2);
}
;
server_max_sent_count: VAR_MAX_SENT_COUNT STRING_ARG
{
OUTYY(("P(server_max_sent_count:%s)\n", $2));
if(atoi($2) == 0 && strcmp($2, "0") != 0)
yyerror("number expected");
else cfg_parser->cfg->max_sent_count = atoi($2);
free($2);
}
;
server_max_query_restarts: VAR_MAX_QUERY_RESTARTS STRING_ARG
{
OUTYY(("P(server_max_query_restarts:%s)\n", $2));
if(atoi($2) == 0 && strcmp($2, "0") != 0)
yyerror("number expected");
else cfg_parser->cfg->max_query_restarts = atoi($2);
free($2);
}
;
server_low_rtt: VAR_LOW_RTT STRING_ARG
{
OUTYY(("P(low-rtt option is deprecated, use fast-server-num instead)\n"));
@@ -2830,14 +2853,6 @@ server_ede: VAR_EDE STRING_ARG
free($2);
}
;
server_upstream_cookies: VAR_UPSTREAM_COOKIES STRING_ARG
{
OUTYY(("P(server_upstream_cookies:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->upstream_cookies = (strcmp($2, "yes")==0);
free($2);
}
server_proxy_protocol_port: VAR_PROXY_PROTOCOL_PORT STRING_ARG
{
OUTYY(("P(server_proxy_protocol_port:%s)\n", $2));
@@ -3716,30 +3731,6 @@ server_tcp_connection_limit: VAR_TCP_CONNECTION_LIMIT STRING_ARG STRING_ARG
}
}
;
server_answer_cookie: VAR_ANSWER_COOKIE STRING_ARG
{
OUTYY(("P(server_answer_cookie:%s)\n", $2));
if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
yyerror("expected yes or no.");
else cfg_parser->cfg->do_answer_cookie = (strcmp($2, "yes")==0);
free($2);
}
;
server_cookie_secret: VAR_COOKIE_SECRET STRING_ARG
{
uint8_t secret[32];
size_t secret_len = sizeof(secret);
OUTYY(("P(server_cookie_secret:%s)\n", $2));
if (sldns_str2wire_hex_buf($2, secret, &secret_len)
|| ( secret_len != 16))
yyerror("expected 128 bit hex string");
else {
cfg_parser->cfg->cookie_secret_len = secret_len;
memcpy(cfg_parser->cfg->cookie_secret, secret, sizeof(secret));
}
free($2);
}
ipsetstart: VAR_IPSET
{
OUTYY(("\nP(ipset:)\n"));
@@ -3809,11 +3800,10 @@ validate_acl_action(const char* action)
strcmp(action, "refuse_non_local")!=0 &&
strcmp(action, "allow_setrd")!=0 &&
strcmp(action, "allow")!=0 &&
strcmp(action, "allow_snoop")!=0 &&
strcmp(action, "allow_cookie")!=0)
strcmp(action, "allow_snoop")!=0)
{
yyerror("expected deny, refuse, deny_non_local, "
"refuse_non_local, allow, allow_setrd, "
"allow_snoop or allow_cookie as access control action");
"refuse_non_local, allow, allow_setrd or "
"allow_snoop as access control action");
}
}
+4 -14
View File
@@ -959,15 +959,14 @@ qinfo_query_encode(sldns_buffer* pkt, struct query_info* qinfo)
}
void
extended_error_encode(sldns_buffer* buf, uint16_t rcode, struct query_info* qinfo,
uint16_t qid, uint16_t qflags, uint16_t xflags, struct edns_data* edns)
error_encode(sldns_buffer* buf, int r, struct query_info* qinfo,
uint16_t qid, uint16_t qflags, struct edns_data* edns)
{
uint16_t flags;
sldns_buffer_clear(buf);
sldns_buffer_write(buf, &qid, sizeof(uint16_t));
flags = (uint16_t)(BIT_QR | BIT_RA | (rcode & 0xF)); /* QR and retcode*/
flags |= xflags;
flags = (uint16_t)(BIT_QR | BIT_RA | r); /* QR and retcode*/
flags |= (qflags & (BIT_RD|BIT_CD)); /* copy RD and CD bit */
sldns_buffer_write_u16(buf, flags);
if(qinfo) flags = 1;
@@ -994,7 +993,7 @@ extended_error_encode(sldns_buffer* buf, uint16_t rcode, struct query_info* qinf
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.ext_rcode = 0;
es.bits &= EDNS_DO;
if(sldns_buffer_limit(buf) + calc_edns_field_size(&es) >
edns->udp_size)
@@ -1002,12 +1001,3 @@ extended_error_encode(sldns_buffer* buf, uint16_t rcode, struct query_info* qinf
attach_edns_record(buf, &es);
}
}
void
error_encode(sldns_buffer* buf, int r, struct query_info* qinfo,
uint16_t qid, uint16_t qflags, struct edns_data* edns)
{
extended_error_encode(buf, (r & 0x000F), qinfo, qid, qflags
, (r & 0xFFF0), edns);
}
+1 -18
View File
@@ -120,7 +120,7 @@ void attach_edns_record(struct sldns_buffer* pkt, struct edns_data* edns);
* Encode an error. With QR and RA set.
*
* @param pkt: where to store the packet.
* @param r: RCODE value to encode (may contain extra flags).
* @param r: RCODE value to encode.
* @param qinfo: if not NULL, the query is included.
* @param qid: query ID to set in packet. network order.
* @param qflags: original query flags (to copy RD and CD bits). host order.
@@ -130,21 +130,4 @@ void attach_edns_record(struct sldns_buffer* pkt, struct edns_data* edns);
void error_encode(struct sldns_buffer* pkt, int r, struct query_info* qinfo,
uint16_t qid, uint16_t qflags, struct edns_data* edns);
/**
* Encode an extended error. With QR and RA set.
*
* @param pkt: where to store the packet.
* @param rcode: Extended RCODE value to encode.
* @param qinfo: if not NULL, the query is included.
* @param qid: query ID to set in packet. network order.
* @param qflags: original query flags (to copy RD and CD bits). host order.
* @param xflags: extra flags to set (such as for example BIT_AA and/or BIT_TC)
* @param edns: if not NULL, this is the query edns info,
* and an edns reply is attached. Only attached if EDNS record fits reply.
* Without edns extended errors (i.e. > 15 )will not be conveyed.
*/
void extended_error_encode(struct sldns_buffer* pkt, uint16_t rcode,
struct query_info* qinfo, uint16_t qid, uint16_t qflags,
uint16_t xflags, struct edns_data* edns);
#endif /* UTIL_DATA_MSGENCODE_H */
+3 -161
View File
@@ -597,19 +597,6 @@ parse_query_section(sldns_buffer* pkt, struct msg_parse* msg)
return 0;
}
struct edns_option*
edns_list_get_option(struct edns_option* option, uint16_t code)
{
while (option) {
if (option->opt_code == code) {
return option;
}
option = option->next;
}
return NULL;
}
size_t
get_rdf_size(sldns_rdf_type rdf)
{
@@ -964,67 +951,11 @@ edns_opt_list_append_keepalive(struct edns_option** list, int msec,
data, region);
}
int siphash(const uint8_t *in, const size_t inlen,
const uint8_t *k, uint8_t *out, const size_t outlen);
/** RFC 1982 comparison, uses unsigned integers, and tries to avoid
* compiler optimization (eg. by avoiding a-b<0 comparisons),
* this routine matches compare_serial(), for SOA serial number checks */
static int
compare_1982(uint32_t a, uint32_t b)
{
/* for 32 bit values */
const uint32_t cutoff = ((uint32_t) 1 << (32 - 1));
if (a == b) {
return 0;
} else if ((a < b && b - a < cutoff) || (a > b && a - b > cutoff)) {
return -1;
} else {
return 1;
}
}
/** if we know that b is larger than a, return the difference between them,
* that is the distance between them. in RFC1982 arith */
static uint32_t
subtract_1982(uint32_t a, uint32_t b)
{
/* for 32 bit values */
const uint32_t cutoff = ((uint32_t) 1 << (32 - 1));
if(a == b)
return 0;
if(a < b && b - a < cutoff) {
return b-a;
}
if(a > b && a - b > cutoff) {
return ((uint32_t)0xffffffff) - (a-b-1);
}
/* wrong case, b smaller than a */
return 0;
}
static uint8_t *
cookie_hash(uint8_t *hash, uint8_t *buf,
struct sockaddr_storage *addr, uint8_t *secret)
{
if (addr->ss_family == AF_INET6) {
memcpy(buf+16, &((struct sockaddr_in6 *)addr)->sin6_addr, 16);
siphash(buf, 32, secret, hash, 8);
} else {
memcpy(buf+16, &((struct sockaddr_in *)addr)->sin_addr, 4);
siphash(buf, 20, secret, hash, 8);
}
return hash;
}
/** parse EDNS options from EDNS wireformat rdata */
static int
parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
struct edns_data* edns, struct config_file* cfg, struct comm_point* c,
struct comm_reply* repinfo, uint32_t now, struct regional* region)
struct regional* region)
{
/* To respond with a Keepalive option, the client connection must have
* received one message with a TCP Keepalive EDNS option, and that
@@ -1048,10 +979,6 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
while(rdata_len >= 4) {
uint16_t opt_code = sldns_read_uint16(rdata_ptr);
uint16_t opt_len = sldns_read_uint16(rdata_ptr+2);
uint8_t server_cookie[40], hash[8];
uint32_t cookie_time, subt_1982;
int comp_1982;
rdata_ptr += 4;
rdata_len -= 4;
if(opt_len > rdata_len)
@@ -1114,86 +1041,6 @@ parse_edns_options_from_query(uint8_t* rdata_ptr, size_t rdata_len,
edns->padding_block_size = cfg->pad_responses_block_size;
break;
case LDNS_EDNS_COOKIE:
if(!cfg || !cfg->do_answer_cookie)
break;
if(opt_len != 8 && (opt_len < 16 || opt_len > 40)) {
verbose(VERB_ALGO, "worker request: "
"badly formatted cookie");
return LDNS_RCODE_FORMERR;
}
edns->cookie_present = 1;
/* Copy client cookie, version and timestamp for
* validation and creation purposes.
*/
memcpy(server_cookie, rdata_ptr, 16);
/* In the "if, if else" block below, we validate a
* RFC9018 cookie. If it doesn't match the recipe, or
* if it doesn't validate, or if the cookie is too old
* (< 30 min), a new cookie is generated.
*/
if (opt_len != 24)
; /* RFC9018 cookies are 24 bytes long */
else if (cfg->cookie_secret_len != 16)
; /* RFC9018 cookies have 16 byte secrets */
else if (rdata_ptr[8] != 1)
; /* RFC9018 cookies are cookie version 1 */
else if ((comp_1982 = compare_1982(now,
(cookie_time = sldns_read_uint32(rdata_ptr + 12)))) > 0
&& (subt_1982 = subtract_1982(cookie_time, now)) > 3600)
; /* Cookie is older than 1 hour
* (see RFC9018 Section 4.3.)
*/
else if (comp_1982 <= 0
&& subtract_1982(now, cookie_time) > 300)
; /* Cookie time is more than 5 minutes in the
* future. (see RFC9018 Section 4.3.)
*/
else if (memcmp( cookie_hash( hash, server_cookie
, &repinfo->remote_addr
, cfg->cookie_secret)
, rdata_ptr + 16 , 8 ) == 0) {
/* Cookie is valid! */
edns->cookie_valid = 1;
if (comp_1982 > 0 && subt_1982 > 1800)
; /* But older than 30 minutes,
* so create a new one anyway */
else if (!edns_opt_list_append( /* Reuse cookie */
&edns->opt_list_out, LDNS_EDNS_COOKIE, opt_len,
rdata_ptr, region)) {
log_err("out of memory");
return LDNS_RCODE_SERVFAIL;
} else
/* Cookie to be reused added to
* outgoing options. Done!
*/
break;
}
/* Add a new server cookie to outgoing cookies */
server_cookie[ 8] = 1; /* Version */
server_cookie[ 9] = 0; /* Reserved */
server_cookie[10] = 0; /* Reserved */
server_cookie[11] = 0; /* Reserved */
sldns_write_uint32(server_cookie + 12, now);
cookie_hash( hash, server_cookie, &repinfo->remote_addr
, cfg->cookie_secret);
memcpy(server_cookie + 16, hash, 8);
if (!edns_opt_list_append( &edns->opt_list_out
, LDNS_EDNS_COOKIE
, 24, server_cookie, region)) {
log_err("out of memory");
return LDNS_RCODE_SERVFAIL;
}
break;
default:
break;
}
@@ -1268,8 +1115,6 @@ parse_extract_edns_from_response_msg(struct msg_parse* msg,
edns->opt_list_out = NULL;
edns->opt_list_inplace_cb_out = NULL;
edns->padding_block_size = 0;
edns->cookie_present = 0;
edns->cookie_valid = 0;
/* take the options */
rdata_len = found->rr_first->size-2;
@@ -1325,8 +1170,7 @@ skip_pkt_rrs(sldns_buffer* pkt, int num)
int
parse_edns_from_query_pkt(sldns_buffer* pkt, struct edns_data* edns,
struct config_file* cfg, struct comm_point* c,
struct comm_reply* repinfo, time_t now, struct regional* region)
struct config_file* cfg, struct comm_point* c, struct regional* region)
{
size_t rdata_len;
uint8_t* rdata_ptr;
@@ -1362,8 +1206,6 @@ parse_edns_from_query_pkt(sldns_buffer* pkt, struct edns_data* edns,
edns->opt_list_out = NULL;
edns->opt_list_inplace_cb_out = NULL;
edns->padding_block_size = 0;
edns->cookie_present = 0;
edns->cookie_valid = 0;
/* take the options */
rdata_len = sldns_buffer_read_u16(pkt);
@@ -1372,7 +1214,7 @@ parse_edns_from_query_pkt(sldns_buffer* pkt, struct edns_data* edns,
rdata_ptr = sldns_buffer_current(pkt);
/* ignore rrsigs */
return parse_edns_options_from_query(rdata_ptr, rdata_len, edns, cfg,
c, repinfo, now, region);
c, region);
}
void
+4 -19
View File
@@ -72,7 +72,6 @@ struct regional;
struct edns_option;
struct config_file;
struct comm_point;
struct comm_reply;
/** number of buckets in parse rrset hash table. Must be power of 2. */
#define PARSE_TABLE_SIZE 32
@@ -218,6 +217,8 @@ struct rr_parse {
* region.
*/
struct edns_data {
/** if EDNS OPT record was present */
int edns_present;
/** Extended RCODE */
uint8_t ext_rcode;
/** The EDNS version number */
@@ -237,13 +238,7 @@ struct edns_data {
struct edns_option* opt_list_inplace_cb_out;
/** block size to pad */
uint16_t padding_block_size;
/** if EDNS OPT record was present */
unsigned int edns_present : 1;
/** if a cookie was present */
unsigned int cookie_present : 1;
/** if the cookie validated */
unsigned int cookie_valid : 1;
};
};
/**
* EDNS option
@@ -259,15 +254,6 @@ struct edns_option {
uint8_t* opt_data;
};
/**
* Search through an EDNS list to find if the specified option.
* @param option: The EDNS list which we search in
* @param code: the option code that we search for
* @return: returns the option if it is there, and NULL when it is not
*/
struct edns_option* edns_list_get_option(struct edns_option* option, uint16_t code);
/**
* Obtain size in the packet of an rr type, that is before dname type.
* Do TYPE_DNAME, and type STR, yourself. Gives size for most regular types.
@@ -329,8 +315,7 @@ int skip_pkt_rrs(struct sldns_buffer* pkt, int num);
* RCODE formerr if OPT is badly formatted and so on.
*/
int parse_edns_from_query_pkt(struct sldns_buffer* pkt, struct edns_data* edns,
struct config_file* cfg, struct comm_point* c,
struct comm_reply* repinfo, time_t now, struct regional* region);
struct config_file* cfg, struct comm_point* c, struct regional* region);
/**
* Calculate hash value for rrset in packet.
+1
View File
@@ -4840,6 +4840,7 @@
8403,
8416,
8417,
8433,
8442,
8443,
8444,
-2
View File
@@ -70,8 +70,6 @@ strmodulevent(enum module_ev e)
case module_event_noreply: return "module_event_noreply";
case module_event_capsfail: return "module_event_capsfail";
case module_event_moddone: return "module_event_moddone";
case module_event_interface_not_available: return
"module_event_interface_not_available";
case module_event_error: return "module_event_error";
}
return "bad_event_value";
-2
View File
@@ -579,8 +579,6 @@ enum module_ev {
module_event_capsfail,
/** next module is done, and its reply is awaiting you */
module_event_moddone,
/** retry of the query is needed with a rewritten (client) cookie */
module_event_interface_not_available,
/** error */
module_event_error
};
+21 -7
View File
@@ -2545,8 +2545,9 @@ comm_point_tcp_handle_write(int fd, struct comm_point* c)
return 1;
}
/** read again to drain buffers when there could be more to read */
static void
/** read again to drain buffers when there could be more to read, returns 0
* on failure which means the comm point is closed. */
static int
tcp_req_info_read_again(int fd, struct comm_point* c)
{
while(c->tcp_req_info->read_again) {
@@ -2563,9 +2564,10 @@ tcp_req_info_read_again(int fd, struct comm_point* c)
(void)(*c->callback)(c, c->cb_arg,
NETEVENT_CLOSED, NULL);
}
return;
return 0;
}
}
return 1;
}
/** read again to drain buffers when there could be more to read */
@@ -2623,6 +2625,9 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
log_assert(c->type == comm_tcp);
ub_comm_base_now(c->ev->base);
if(c->fd == -1 || c->fd != fd)
return; /* duplicate event, but commpoint closed. */
#ifdef USE_DNSCRYPT
/* Initialize if this is a dnscrypt socket */
if(c->tcp_parent) {
@@ -2671,8 +2676,10 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
}
return;
}
if(has_tcpq && c->tcp_req_info && c->tcp_req_info->read_again)
tcp_req_info_read_again(fd, c);
if(has_tcpq && c->tcp_req_info && c->tcp_req_info->read_again) {
if(!tcp_req_info_read_again(fd, c))
return;
}
if(moreread && *moreread)
tcp_more_read_again(fd, c);
return;
@@ -2690,8 +2697,10 @@ comm_point_tcp_handle_callback(int fd, short event, void* arg)
}
return;
}
if(has_tcpq && c->tcp_req_info && c->tcp_req_info->read_again)
tcp_req_info_read_again(fd, c);
if(has_tcpq && c->tcp_req_info && c->tcp_req_info->read_again) {
if(!tcp_req_info_read_again(fd, c))
return;
}
if(morewrite && *morewrite)
tcp_more_write_again(fd, c);
return;
@@ -4488,6 +4497,11 @@ comm_point_close(struct comm_point* c)
tcp_req_info_clear(c->tcp_req_info);
if(c->h2_session)
http2_session_server_delete(c->h2_session);
/* stop the comm point from reading or writing after it is closed. */
if(c->tcp_more_read_again && *c->tcp_more_read_again)
*c->tcp_more_read_again = 0;
if(c->tcp_more_write_again && *c->tcp_more_write_again)
*c->tcp_more_write_again = 0;
/* close fd after removing from event lists, or epoll.. is messed up */
if(c->fd != -1 && !c->do_not_close) {
-4
View File
@@ -99,10 +99,6 @@ typedef int comm_point_callback_type(struct comm_point*, void*, int,
/** to pass write of the write packet is done to callback function
* used when tcp_write_and_read is enabled */
#define NETEVENT_PKT_WRITTEN -5
/** to pass a retry event when the bound interface of a cookie has failed
* and a retry is needed with a rewritten (client) cookie */
#define NETEVENT_BOUND_INTERFACE_NOT_AVAILABLE -6
/** timeout to slow accept calls when not possible, in msec. */
#define NETEVENT_SLOW_ACCEPT_TIME 2000
-165
View File
@@ -1,165 +0,0 @@
/*
SipHash reference C implementation
Copyright (c) 2012-2016 Jean-Philippe Aumasson
<jeanphilippe.aumasson@gmail.com>
Copyright (c) 2012-2014 Daniel J. Bernstein <djb@cr.yp.to>
To the extent possible under law, the author(s) have dedicated all copyright
and related and neighboring rights to this software to the public domain
worldwide. This software is distributed without any warranty.
You should have received a copy of the CC0 Public Domain Dedication along
with
this software. If not, see
<http://creativecommons.org/publicdomain/zero/1.0/>.
*/
#include <assert.h>
#include <stdint.h>
#include <stdio.h>
#include <string.h>
/* default: SipHash-2-4 */
#define cROUNDS 2
#define dROUNDS 4
#define ROTL(x, b) (uint64_t)(((x) << (b)) | ((x) >> (64 - (b))))
#define U32TO8_LE(p, v) \
(p)[0] = (uint8_t)((v)); \
(p)[1] = (uint8_t)((v) >> 8); \
(p)[2] = (uint8_t)((v) >> 16); \
(p)[3] = (uint8_t)((v) >> 24);
#define U64TO8_LE(p, v) \
U32TO8_LE((p), (uint32_t)((v))); \
U32TO8_LE((p) + 4, (uint32_t)((v) >> 32));
#define U8TO64_LE(p) \
(((uint64_t)((p)[0])) | ((uint64_t)((p)[1]) << 8) | \
((uint64_t)((p)[2]) << 16) | ((uint64_t)((p)[3]) << 24) | \
((uint64_t)((p)[4]) << 32) | ((uint64_t)((p)[5]) << 40) | \
((uint64_t)((p)[6]) << 48) | ((uint64_t)((p)[7]) << 56))
#define SIPROUND \
do { \
v0 += v1; \
v1 = ROTL(v1, 13); \
v1 ^= v0; \
v0 = ROTL(v0, 32); \
v2 += v3; \
v3 = ROTL(v3, 16); \
v3 ^= v2; \
v0 += v3; \
v3 = ROTL(v3, 21); \
v3 ^= v0; \
v2 += v1; \
v1 = ROTL(v1, 17); \
v1 ^= v2; \
v2 = ROTL(v2, 32); \
} while (0)
#ifdef DEBUG
#define TRACE \
do { \
printf("(%3d) v0 %08x %08x\n", (int)inlen, (uint32_t)(v0 >> 32), \
(uint32_t)v0); \
printf("(%3d) v1 %08x %08x\n", (int)inlen, (uint32_t)(v1 >> 32), \
(uint32_t)v1); \
printf("(%3d) v2 %08x %08x\n", (int)inlen, (uint32_t)(v2 >> 32), \
(uint32_t)v2); \
printf("(%3d) v3 %08x %08x\n", (int)inlen, (uint32_t)(v3 >> 32), \
(uint32_t)v3); \
} while (0)
#else
#define TRACE
#endif
int siphash(const uint8_t *in, const size_t inlen, const uint8_t *k,
uint8_t *out, const size_t outlen) {
assert((outlen == 8) || (outlen == 16));
uint64_t v0 = 0x736f6d6570736575ULL;
uint64_t v1 = 0x646f72616e646f6dULL;
uint64_t v2 = 0x6c7967656e657261ULL;
uint64_t v3 = 0x7465646279746573ULL;
uint64_t k0 = U8TO64_LE(k);
uint64_t k1 = U8TO64_LE(k + 8);
uint64_t m;
int i;
const uint8_t *end = in + inlen - (inlen % sizeof(uint64_t));
const int left = inlen & 7;
uint64_t b = ((uint64_t)inlen) << 56;
v3 ^= k1;
v2 ^= k0;
v1 ^= k1;
v0 ^= k0;
if (outlen == 16)
v1 ^= 0xee;
for (; in != end; in += 8) {
m = U8TO64_LE(in);
v3 ^= m;
TRACE;
for (i = 0; i < cROUNDS; ++i)
SIPROUND;
v0 ^= m;
}
switch (left) {
case 7:
b |= ((uint64_t)in[6]) << 48;
case 6:
b |= ((uint64_t)in[5]) << 40;
case 5:
b |= ((uint64_t)in[4]) << 32;
case 4:
b |= ((uint64_t)in[3]) << 24;
case 3:
b |= ((uint64_t)in[2]) << 16;
case 2:
b |= ((uint64_t)in[1]) << 8;
case 1:
b |= ((uint64_t)in[0]);
break;
case 0:
break;
}
v3 ^= b;
TRACE;
for (i = 0; i < cROUNDS; ++i)
SIPROUND;
v0 ^= b;
if (outlen == 16)
v2 ^= 0xee;
else
v2 ^= 0xff;
TRACE;
for (i = 0; i < dROUNDS; ++i)
SIPROUND;
b = v0 ^ v1 ^ v2 ^ v3;
U64TO8_LE(out, b);
if (outlen == 8)
return 0;
v1 ^= 0xdd;
TRACE;
for (i = 0; i < dROUNDS; ++i)
SIPROUND;
b = v0 ^ v1 ^ v2 ^ v3;
U64TO8_LE(out + 8, b);
return 0;
}
+34 -19
View File
@@ -45,6 +45,9 @@
#include "util/netevent.h"
#include "util/fptr_wlist.h"
#include "util/ub_event.h"
#ifdef HAVE_POLL_H
#include <poll.h>
#endif
#ifndef USE_WINSOCK
/* on unix */
@@ -396,20 +399,28 @@ int tube_read_msg(struct tube* tube, uint8_t** buf, uint32_t* len,
return 1;
}
/** perform a select() on the fd */
/** perform poll() on the fd */
static int
pollit(int fd, struct timeval* t)
{
fd_set r;
struct pollfd fds;
int pret;
int msec = -1;
memset(&fds, 0, sizeof(fds));
fds.fd = fd;
fds.events = POLLIN | POLLERR | POLLHUP;
#ifndef S_SPLINT_S
FD_ZERO(&r);
FD_SET(FD_SET_T fd, &r);
if(t)
msec = t->tv_sec*1000 + t->tv_usec/1000;
#endif
if(select(fd+1, &r, NULL, NULL, t) == -1) {
pret = poll(&fds, 1, msec);
if(pret == -1)
return 0;
}
errno = 0;
return (int)(FD_ISSET(fd, &r));
if(pret != 0)
return 1;
return 0;
}
int tube_poll(struct tube* tube)
@@ -426,24 +437,27 @@ int tube_wait(struct tube* tube)
int tube_wait_timeout(struct tube* tube, int msec)
{
struct timeval t;
int fd = tube->sr;
fd_set r;
t.tv_sec = msec/1000;
t.tv_usec = (msec%1000)*1000;
#ifndef S_SPLINT_S
FD_ZERO(&r);
FD_SET(FD_SET_T fd, &r);
#endif
int ret = 0;
while(1) {
if(select(fd+1, &r, NULL, NULL, &t) == -1) {
struct pollfd fds;
memset(&fds, 0, sizeof(fds));
fds.fd = tube->sr;
fds.events = POLLIN | POLLERR | POLLHUP;
ret = poll(&fds, 1, msec);
if(ret == -1) {
if(errno == EAGAIN || errno == EINTR)
continue;
return -1;
}
break;
}
return (int)(FD_ISSET(fd, &r));
if(ret != 0)
return 1;
return 0;
}
int tube_read_fd(struct tube* tube)
@@ -529,6 +543,7 @@ struct tube* tube_create(void)
if(tube->event == WSA_INVALID_EVENT) {
free(tube);
log_err("WSACreateEvent: %s", wsa_strerror(WSAGetLastError()));
return NULL;
}
if(!WSAResetEvent(tube->event)) {
log_err("WSAResetEvent: %s", wsa_strerror(WSAGetLastError()));
-2
View File
@@ -2376,8 +2376,6 @@ probe_anchor(struct module_env* env, struct trust_anchor* tp)
edns.opt_list_out = NULL;
edns.opt_list_inplace_cb_out = NULL;
edns.padding_block_size = 0;
edns.cookie_present = 0;
edns.cookie_valid = 0;
if(sldns_buffer_capacity(buf) < 65535)
edns.udp_size = (uint16_t)sldns_buffer_capacity(buf);
else edns.udp_size = 65535;