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/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/timehist.c util/tube.c \
util/ub_event.c util/ub_event_pluggable.c util/winsock_event.c \
validator/autotrust.c validator/val_anchor.c validator/validator.c \
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 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 timehist.lo tube.lo winsock_event.lo autotrust.lo val_anchor.lo \
validator.lo val_kcache.lo val_kentry.lo val_neg.lo val_nsec3.lo val_nsec.lo \
$(srcdir)/util/config_file.h $(srcdir)/util/storage/lookup3.h $(srcdir)/util/net_help.h \
$(srcdir)/util/data/dname.h $(srcdir)/util/data/msgencode.h $(srcdir)/iterator/iter_fwd.h \
$(srcdir)/iterator/iter_hints.h $(srcdir)/sldns/str2wire.h
-unbound-host.lo unbound-host.o: $(srcdir)/smallapp/unbound-host.c config.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h \
-
-asynclook.lo asynclook.o: $(srcdir)/testcode/asynclook.c config.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
+unbound-host.lo unbound-host.o: $(srcdir)/smallapp/unbound-host.c \
+ config.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h
+asynclook.lo asynclook.o: $(srcdir)/testcode/asynclook.c \
+ config.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/libunbound/context.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
$(srcdir)/util/alloc.h $(srcdir)/util/rbtree.h $(srcdir)/services/modstack.h \
$(srcdir)/libunbound/unbound-event.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/rrdef.h \
-
-streamtcp.lo streamtcp.o: $(srcdir)/testcode/streamtcp.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/net_help.h $(srcdir)/util/data/msgencode.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h \
-
-perf.lo perf.o: $(srcdir)/testcode/perf.c config.h $(srcdir)/util/log.h $(srcdir)/util/locks.h \
- $(srcdir)/testcode/checklocks.h $(srcdir)/util/net_help.h $(srcdir)/util/data/msgencode.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/packed_rrset.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h
-delayer.lo delayer.o: $(srcdir)/testcode/delayer.c config.h $(srcdir)/util/net_help.h $(srcdir)/util/log.h \
- $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
-unbound-control.lo unbound-control.o: $(srcdir)/smallapp/unbound-control.c config.h \
- $(srcdir)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/util/locks.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/net_help.h $(srcdir)/util/shm_side/shm_main.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/pkthdr.h
-unbound-anchor.lo unbound-anchor.o: $(srcdir)/smallapp/unbound-anchor.c config.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h \
-
-petal.lo petal.o: $(srcdir)/testcode/petal.c config.h \
-
-pythonmod_utils.lo pythonmod_utils.o: $(srcdir)/pythonmod/pythonmod_utils.c config.h $(srcdir)/util/module.h \
- $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
- $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
- $(srcdir)/dnscrypt/cert.h $(srcdir)/util/net_help.h \
- $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h $(srcdir)/util/storage/slabhash.h \
- $(srcdir)/util/regional.h $(srcdir)/iterator/iter_delegpt.h $(srcdir)/sldns/sbuffer.h \
-
-win_svc.lo win_svc.o: $(srcdir)/winrc/win_svc.c config.h $(srcdir)/winrc/win_svc.h $(srcdir)/winrc/w_inst.h \
- $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/testcode/checklocks.h \
- $(srcdir)/util/alloc.h $(srcdir)/services/modstack.h \
- $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h \
- $(srcdir)/sldns/sbuffer.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h \
- $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/dnscrypt/cert.h $(srcdir)/util/data/msgreply.h \
- $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h \
- $(srcdir)/util/timehist.h $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h \
- $(srcdir)/daemon/remote.h \
- $(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h $(srcdir)/util/net_help.h
-w_inst.lo w_inst.o: $(srcdir)/winrc/w_inst.c config.h $(srcdir)/winrc/w_inst.h $(srcdir)/winrc/win_svc.h
-unbound-service-install.lo unbound-service-install.o: $(srcdir)/winrc/unbound-service-install.c config.h \
- $(srcdir)/winrc/w_inst.h
-unbound-service-remove.lo unbound-service-remove.o: $(srcdir)/winrc/unbound-service-remove.c config.h \
- $(srcdir)/winrc/w_inst.h
-anchor-update.lo anchor-update.o: $(srcdir)/winrc/anchor-update.c config.h $(srcdir)/libunbound/unbound.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/wire2str.h
-keyraw.lo keyraw.o: $(srcdir)/sldns/keyraw.c config.h $(srcdir)/sldns/keyraw.h \
- $(srcdir)/sldns/rrdef.h \
-
-sbuffer.lo sbuffer.o: $(srcdir)/sldns/sbuffer.c config.h $(srcdir)/sldns/sbuffer.h
-wire2str.lo wire2str.o: $(srcdir)/sldns/wire2str.c config.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/str2wire.h \
- $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/sbuffer.h \
- $(srcdir)/sldns/keyraw.h \
-
-parse.lo parse.o: $(srcdir)/sldns/parse.c config.h $(srcdir)/sldns/parse.h $(srcdir)/sldns/parseutil.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/rrdef.h
+streamtcp.lo streamtcp.o: $(srcdir)/testcode/streamtcp.c \
+ config.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h $(srcdir)/util/net_help.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/dname.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/wire2str.h
+perf.lo perf.o: $(srcdir)/testcode/perf.c \
+ config.h $(srcdir)/util/log.h \
+ $(srcdir)/util/locks.h $(srcdir)/util/net_help.h $(srcdir)/util/data/msgencode.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/wire2str.h \
+ $(srcdir)/sldns/str2wire.h
+delayer.lo delayer.o: $(srcdir)/testcode/delayer.c \
+ config.h $(srcdir)/util/net_help.h \
+ $(srcdir)/util/log.h $(srcdir)/util/config_file.h $(srcdir)/sldns/sbuffer.h
+unbound-control.lo unbound-control.o: $(srcdir)/smallapp/unbound-control.c \
+ config.h $(srcdir)/util/log.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/locks.h $(srcdir)/util/net_help.h $(srcdir)/util/shm_side/shm_main.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h $(srcdir)/sldns/wire2str.h \
+ $(srcdir)/sldns/pkthdr.h
+unbound-anchor.lo unbound-anchor.o: $(srcdir)/smallapp/unbound-anchor.c \
+ config.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h
+petal.lo petal.o: $(srcdir)/testcode/petal.c \
+ config.h
+pythonmod_utils.lo pythonmod_utils.o: $(srcdir)/pythonmod/pythonmod_utils.c \
+ config.h $(srcdir)/util/module.h \
+ $(srcdir)/util/storage/lruhash.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/data/msgreply.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/data/msgparse.h $(srcdir)/sldns/pkthdr.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/util/netevent.h $(srcdir)/dnscrypt/dnscrypt.h \
+ $(srcdir)/util/net_help.h $(srcdir)/services/cache/dns.h $(srcdir)/services/cache/rrset.h \
+ $(srcdir)/util/storage/slabhash.h $(srcdir)/util/regional.h $(srcdir)/iterator/iter_delegpt.h \
$(srcdir)/sldns/sbuffer.h
-parseutil.lo parseutil.o: $(srcdir)/sldns/parseutil.c config.h $(srcdir)/sldns/parseutil.h
-rrdef.lo rrdef.o: $(srcdir)/sldns/rrdef.c config.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/parseutil.h
-str2wire.lo str2wire.o: $(srcdir)/sldns/str2wire.c config.h $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h \
- $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parse.h $(srcdir)/sldns/parseutil.h
-ctime_r.lo ctime_r.o: $(srcdir)/compat/ctime_r.c config.h $(srcdir)/util/locks.h $(srcdir)/util/log.h \
- $(srcdir)/testcode/checklocks.h
-fake-rfc2553.lo fake-rfc2553.o: $(srcdir)/compat/fake-rfc2553.c $(srcdir)/compat/fake-rfc2553.h config.h
-gmtime_r.lo gmtime_r.o: $(srcdir)/compat/gmtime_r.c config.h
-inet_aton.lo inet_aton.o: $(srcdir)/compat/inet_aton.c config.h
-inet_ntop.lo inet_ntop.o: $(srcdir)/compat/inet_ntop.c config.h
-inet_pton.lo inet_pton.o: $(srcdir)/compat/inet_pton.c config.h
-malloc.lo malloc.o: $(srcdir)/compat/malloc.c config.h
-memcmp.lo memcmp.o: $(srcdir)/compat/memcmp.c config.h
-memmove.lo memmove.o: $(srcdir)/compat/memmove.c config.h
-snprintf.lo snprintf.o: $(srcdir)/compat/snprintf.c config.h
-strlcat.lo strlcat.o: $(srcdir)/compat/strlcat.c config.h
-strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c config.h
-strptime.lo strptime.o: $(srcdir)/compat/strptime.c config.h
-getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c config.h \
-
-getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c config.h
-getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c config.h \
-
+win_svc.lo win_svc.o: $(srcdir)/winrc/win_svc.c \
+ config.h $(srcdir)/winrc/win_svc.h \
+ $(srcdir)/winrc/w_inst.h $(srcdir)/daemon/daemon.h $(srcdir)/util/locks.h $(srcdir)/util/log.h $(srcdir)/util/alloc.h \
+ $(srcdir)/services/modstack.h \
+ $(srcdir)/daemon/worker.h $(srcdir)/libunbound/worker.h $(srcdir)/sldns/sbuffer.h \
+ $(srcdir)/util/data/packed_rrset.h $(srcdir)/util/storage/lruhash.h $(srcdir)/util/netevent.h \
+ $(srcdir)/dnscrypt/dnscrypt.h $(srcdir)/util/data/msgreply.h $(srcdir)/util/data/msgparse.h \
+ $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/rrdef.h $(srcdir)/daemon/stats.h $(srcdir)/util/timehist.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/util/module.h $(srcdir)/dnstap/dnstap.h $(srcdir)/daemon/remote.h \
+ $(srcdir)/util/config_file.h $(srcdir)/util/ub_event.h $(srcdir)/util/net_help.h
+w_inst.lo w_inst.o: $(srcdir)/winrc/w_inst.c \
+ config.h $(srcdir)/winrc/w_inst.h \
+ $(srcdir)/winrc/win_svc.h
+unbound-service-install.lo unbound-service-install.o: $(srcdir)/winrc/unbound-service-install.c \
+ config.h $(srcdir)/winrc/w_inst.h
+unbound-service-remove.lo unbound-service-remove.o: $(srcdir)/winrc/unbound-service-remove.c \
+ config.h $(srcdir)/winrc/w_inst.h
+anchor-update.lo anchor-update.o: $(srcdir)/winrc/anchor-update.c \
+ config.h \
+ $(srcdir)/libunbound/unbound.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/wire2str.h
+keyraw.lo keyraw.o: $(srcdir)/sldns/keyraw.c \
+ config.h $(srcdir)/sldns/keyraw.h \
+ $(srcdir)/sldns/rrdef.h
+sbuffer.lo sbuffer.o: $(srcdir)/sldns/sbuffer.c \
+ config.h $(srcdir)/sldns/sbuffer.h
+wire2str.lo wire2str.o: $(srcdir)/sldns/wire2str.c \
+ config.h $(srcdir)/sldns/wire2str.h \
+ $(srcdir)/sldns/str2wire.h $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/pkthdr.h $(srcdir)/sldns/parseutil.h \
+ $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/keyraw.h
+parse.lo parse.o: $(srcdir)/sldns/parse.c \
+ config.h $(srcdir)/sldns/parse.h \
+ $(srcdir)/sldns/parseutil.h $(srcdir)/sldns/sbuffer.h
+parseutil.lo parseutil.o: $(srcdir)/sldns/parseutil.c \
+ config.h \
+ $(srcdir)/sldns/parseutil.h
+rrdef.lo rrdef.o: $(srcdir)/sldns/rrdef.c \
+ config.h $(srcdir)/sldns/rrdef.h \
+ $(srcdir)/sldns/parseutil.h
+str2wire.lo str2wire.o: $(srcdir)/sldns/str2wire.c \
+ config.h $(srcdir)/sldns/str2wire.h \
+ $(srcdir)/sldns/rrdef.h $(srcdir)/sldns/wire2str.h $(srcdir)/sldns/sbuffer.h $(srcdir)/sldns/parse.h \
+ $(srcdir)/sldns/parseutil.h
+ctime_r.lo ctime_r.o: $(srcdir)/compat/ctime_r.c \
+ config.h $(srcdir)/util/locks.h \
+ $(srcdir)/util/log.h
+fake-rfc2553.lo fake-rfc2553.o: $(srcdir)/compat/fake-rfc2553.c $(srcdir)/compat/fake-rfc2553.h \
+ config.h
+gmtime_r.lo gmtime_r.o: $(srcdir)/compat/gmtime_r.c \
+ config.h
+inet_aton.lo inet_aton.o: $(srcdir)/compat/inet_aton.c \
+ config.h
+inet_ntop.lo inet_ntop.o: $(srcdir)/compat/inet_ntop.c \
+ config.h
+inet_pton.lo inet_pton.o: $(srcdir)/compat/inet_pton.c \
+ config.h
+malloc.lo malloc.o: $(srcdir)/compat/malloc.c \
+ config.h
+memcmp.lo memcmp.o: $(srcdir)/compat/memcmp.c \
+ config.h
+memmove.lo memmove.o: $(srcdir)/compat/memmove.c \
+ config.h
+snprintf.lo snprintf.o: $(srcdir)/compat/snprintf.c \
+ config.h
+strlcat.lo strlcat.o: $(srcdir)/compat/strlcat.c \
+ config.h
+strlcpy.lo strlcpy.o: $(srcdir)/compat/strlcpy.c \
+ config.h
+strptime.lo strptime.o: $(srcdir)/compat/strptime.c \
+ config.h
+getentropy_linux.lo getentropy_linux.o: $(srcdir)/compat/getentropy_linux.c \
+ config.h
+getentropy_osx.lo getentropy_osx.o: $(srcdir)/compat/getentropy_osx.c \
+ config.h
+getentropy_solaris.lo getentropy_solaris.o: $(srcdir)/compat/getentropy_solaris.c \
+ config.h
getentropy_win.lo getentropy_win.o: $(srcdir)/compat/getentropy_win.c
-explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c config.h
-arc4random.lo arc4random.o: $(srcdir)/compat/arc4random.c config.h $(srcdir)/compat/chacha_private.h
-arc4random_uniform.lo arc4random_uniform.o: $(srcdir)/compat/arc4random_uniform.c config.h
-arc4_lock.lo arc4_lock.o: $(srcdir)/compat/arc4_lock.c config.h $(srcdir)/util/locks.h
-sha512.lo sha512.o: $(srcdir)/compat/sha512.c config.h
-reallocarray.lo reallocarray.o: $(srcdir)/compat/reallocarray.c config.h
-isblank.lo isblank.o: $(srcdir)/compat/isblank.c config.h
-strsep.lo strsep.o: $(srcdir)/compat/strsep.c config.h
+explicit_bzero.lo explicit_bzero.o: $(srcdir)/compat/explicit_bzero.c \
+ config.h
+arc4random.lo arc4random.o: $(srcdir)/compat/arc4random.c \
+ config.h \
+ $(srcdir)/compat/chacha_private.h
+arc4random_uniform.lo arc4random_uniform.o: $(srcdir)/compat/arc4random_uniform.c \
+ config.h
+arc4_lock.lo arc4_lock.o: $(srcdir)/compat/arc4_lock.c \
+ config.h $(srcdir)/util/locks.h
+sha512.lo sha512.o: $(srcdir)/compat/sha512.c \
+ config.h
+reallocarray.lo reallocarray.o: $(srcdir)/compat/reallocarray.c \
+ config.h
+isblank.lo isblank.o: $(srcdir)/compat/isblank.c \
+ config.h
+strsep.lo strsep.o: $(srcdir)/compat/strsep.c \
+ config.h
#include "util/data/dname.h"
#include "util/fptr_wlist.h"
#include "util/tube.h"
+#include "util/edns.h"
#include "iterator/iter_fwd.h"
#include "iterator/iter_hints.h"
#include "validator/autotrust.h"
* Then check if it needs validation, if so, this routine fails,
* so that iterator can prime and validator can verify rrsets.
*/
+ struct edns_data edns_bak;
uint16_t udpsize = edns->udp_size;
int secure = 0;
time_t timenow = *worker->env.now;
}
}
/* return this delegation from the cache */
+ edns_bak = *edns;
edns->edns_version = EDNS_ADVERTISED_VERSION;
edns->udp_size = EDNS_ADVERTISED_SIZE;
edns->ext_rcode = 0;
(int)(flags&LDNS_RCODE_MASK), edns, worker->scratchpad))
return 0;
msg->rep->flags |= BIT_QR|BIT_RA;
- if(!reply_info_answer_encode(&msg->qinfo, msg->rep, id, flags,
+ if(!apply_edns_options(edns, &edns_bak, worker->env.cfg,
+ repinfo->c, worker->scratchpad) ||
+ !reply_info_answer_encode(&msg->qinfo, msg->rep, id, flags,
repinfo->c->buffer, 0, 1, worker->scratchpad,
udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
struct reply_info* rep, uint16_t id, uint16_t flags,
struct comm_reply* repinfo, struct edns_data* edns)
{
+ struct edns_data edns_bak;
time_t timenow = *worker->env.now;
uint16_t udpsize = edns->udp_size;
struct reply_info* encode_rep = rep;
}
} else secure = 0;
+ edns_bak = *edns;
edns->edns_version = EDNS_ADVERTISED_VERSION;
edns->udp_size = EDNS_ADVERTISED_SIZE;
edns->ext_rcode = 0;
if(!*partial_repp)
goto bail_out;
}
- } else if(!reply_info_answer_encode(qinfo, encode_rep, id, flags,
+ } else if(!apply_edns_options(edns, &edns_bak, worker->env.cfg,
+ repinfo->c, worker->scratchpad) ||
+ !reply_info_answer_encode(qinfo, encode_rep, id, flags,
repinfo->c->buffer, timenow, 1, worker->scratchpad,
udpsize, edns, (int)(edns->bits & EDNS_DO), secure)) {
if(!inplace_cb_reply_servfail_call(&worker->env, qinfo, NULL, NULL,
log_addr(VERB_CLIENT,"from",&repinfo->addr, repinfo->addrlen);
edns.udp_size = NORMAL_UDP_SIZE;
}
- edns_opt = edns_opt_list_find(edns.opt_list, LDNS_EDNS_KEEPALIVE);
- if(edns_opt && c->type != comm_udp) {
- if(edns_opt->opt_len > 0) {
+ if(c->type != comm_udp) {
+ edns_opt = edns_opt_list_find(edns.opt_list, LDNS_EDNS_KEEPALIVE);
+ if(edns_opt && edns_opt->opt_len > 0) {
edns.ext_rcode = 0;
edns.edns_version = EDNS_ADVERTISED_VERSION;
edns.udp_size = EDNS_ADVERTISED_SIZE;
}
worker->front = listen_create(worker->base, ports,
cfg->msg_buffer_size, (int)cfg->incoming_num_tcp,
- cfg->tcp_idle_timeout, worker->daemon->listen_sslctx,
+ cfg->do_tcp_keepalive
+ ? cfg->tcp_keepalive_timeout
+ : cfg->tcp_idle_timeout,
+ worker->daemon->listen_sslctx,
dtenv, worker_handle_request, worker);
if(!worker->front) {
log_err("could not create listening sockets");
If this timeout expires Unbound closes the connection.
This option defaults to 30000 milliseconds.
.TP
+.B edns-tcp-keepalive: \fI<yes or no>\fR
+Enable or disable EDNS TCP Keepalive. Default is no.
+.TP
+.B edns-tcp-keepalive-timeout: \fI<msec>\fR
+The period Unbound will wait for a query on a TCP connection when
+EDNS TCP Keepalive is active. If this timeout expires Unbound closes
+the connection. This option defaults to 120000 milliseconds.
+Unbound sends this value less 200 milliseconds in the EDNS TCP Keepalive
+option to give the client time to close the connection before the server
+times out.
+.TP
.B tcp\-upstream: \fI<yes or no>
Enable or disable whether the upstream queries use TCP only for transport.
Default is no. Useful in tunneling scenarios.
#include "util/fptr_wlist.h"
#include "util/alloc.h"
#include "util/config_file.h"
+#include "util/edns.h"
#include "sldns/sbuffer.h"
#include "sldns/wire2str.h"
#include "services/localzone.h"
m->s.qinfo.local_alias = r->local_alias;
if(!inplace_cb_reply_call(m->s.env, &m->s.qinfo, &m->s, rep,
LDNS_RCODE_NOERROR, &r->edns, m->s.region) ||
+ !apply_edns_options(&r->edns, &edns_bak,
+ &m->s.env->cfg, r->query_reply.c,
+ m->s.region) ||
!reply_info_answer_encode(&m->s.qinfo, rep, r->qid,
r->qflags, r->query_reply.c->buffer, 0, 1,
m->s.env->scratch, udp_size, &r->edns,
c.fd = -1;
c.buffer = sldns_buffer_new(runtime->bufsize);
c.type = comm_udp;
- if(pend->transport == transport_tcp)
+ if(pend->transport == transport_tcp) {
c.type = comm_tcp;
+ c.tcp_timeout_msec = 30000;
+ c.tcp_keepalive = runtime->tcp_seen_keepalive;
+ }
fill_buffer_with_reply(c.buffer, entry, pend->pkt, pend->pkt_len,
pend->tcp_pkt_counter);
repinfo.c = &c;
else runtime->answer_list = ans->next;
if(!ans->next)
runtime->answer_last = prev;
+ if(ans->repinfo.c->tcp_keepalive)
+ runtime->tcp_seen_keepalive = 1;
delete_replay_answer(ans);
return;
} else {
repinfo.c->fd = -1;
repinfo.c->ev = (struct internal_event*)runtime;
repinfo.c->buffer = sldns_buffer_new(runtime->bufsize);
- if(todo->match->match_transport == transport_tcp)
+ if(todo->match->match_transport == transport_tcp) {
repinfo.c->type = comm_tcp;
- else repinfo.c->type = comm_udp;
+ repinfo.c->tcp_timeout_msec = 30000;
+ repinfo.c->tcp_keepalive = runtime->tcp_seen_keepalive;
+ } else
+ repinfo.c->type = comm_udp;
fill_buffer_with_reply(repinfo.c->buffer, todo->match, NULL, 0, 0);
log_info("testbound: incoming QUERY");
log_pkt("query pkt", todo->match->reply_list->reply_pkt,
cb = p->callback;
c.buffer = sldns_buffer_new(runtime->bufsize);
c.type = comm_udp;
- if(p->transport == transport_tcp)
+ if(p->transport == transport_tcp) {
c.type = comm_tcp;
+ c.tcp_timeout_msec = 30000;
+ c.tcp_keepalive = runtime->tcp_seen_keepalive;
+ }
if(todo->evt_type == repevt_back_reply && todo->match) {
fill_buffer_with_reply(c.buffer, todo->match, p->pkt,
p->pkt_len, p->tcp_pkt_counter);
/** the current time in microseconds */
struct timeval now_tv;
+ /** has TCP connection seen a keepalive? */
+ int tcp_seen_keepalive;
+
/** signal handler callback */
void (*sig_cb)(int, void*);
/** signal handler user arg */
server:
verbosity: 3
+ edns-tcp-keepalive: yes
+ edns-tcp-keepalive-timeout: 30000 # Hardwired to this in fake_event.c
stub-zone:
name: "."
stub-addr: 193.0.14.129 # K.ROOT-SERVERS.NET.
SECTION ANSWER
. IN NS K.ROOT-SERVERS.NET.
SECTION ADDITIONAL
+ HEX_EDNSDATA_BEGIN
+ 00 0b ; Opcode 11
+ 00 02 ; Length 2
+ 01 2c ; 30s = 300 10th secs
+ HEX_EDNSDATA_END
+ K.ROOT-SERVERS.NET. IN A 193.0.14.129
+ ENTRY_END
+
+; Check that a subsequent query on the connection without keepalive will
+; generate a keepalive reply because we've already seen one.
+
+STEP 40 QUERY
+
+ ENTRY_BEGIN
+ MATCH TCP ednsdata
+ REPLY RD
+ SECTION QUESTION
+ . IN NS
+ SECTION ADDITIONAL
+ HEX_EDNSDATA_BEGIN
+ ; Empty
+ HEX_EDNSDATA_END
+ ENTRY_END
+
+STEP 50 CHECK_ANSWER
+
+ ENTRY_BEGIN
+ MATCH TCP ednsdata
+ REPLY QR RD RA NOERROR
+ SECTION QUESTION
+ . IN NS
+ SECTION ANSWER
+ . IN NS K.ROOT-SERVERS.NET.
+ SECTION ADDITIONAL
+ HEX_EDNSDATA_BEGIN
+ 00 0b ; Opcode 11
+ 00 02 ; Length 2
+ 01 2c ; 30s = 300 10th secs
+ HEX_EDNSDATA_END
K.ROOT-SERVERS.NET. IN A 193.0.14.129
ENTRY_END
cfg->tcp_mss = 0;
cfg->outgoing_tcp_mss = 0;
cfg->tcp_idle_timeout = 30 * 1000; /* 30s in millisecs */
+ cfg->do_tcp_keepalive = 0;
+ cfg->tcp_keepalive_timeout = 120 * 1000; /* 120s in millisecs */
cfg->ssl_service_key = NULL;
cfg->ssl_service_pem = NULL;
cfg->ssl_port = UNBOUND_DNS_OVER_TLS_PORT;
else S_NUMBER_NONZERO("tcp-mss:", tcp_mss)
else S_NUMBER_NONZERO("outgoing-tcp-mss:", outgoing_tcp_mss)
else S_NUMBER_NONZERO("tcp-idle-timeout:", tcp_idle_timeout)
+ else S_YNO("edns-tcp-keepalive:", do_tcp_keepalive)
+ else S_NUMBER_NONZERO("edns-tcp-keepalive-timeout:", tcp_keepalive_timeout)
else S_YNO("ssl-upstream:", ssl_upstream)
else S_STR("ssl-service-key:", ssl_service_key)
else S_STR("ssl-service-pem:", ssl_service_pem)
else O_DEC(opt, "tcp-mss", tcp_mss)
else O_DEC(opt, "outgoing-tcp-mss", outgoing_tcp_mss)
else O_DEC(opt, "tcp-idle-timeout", tcp_idle_timeout)
+ else O_YNO(opt, "edns-tcp-keepalive", do_tcp_keepalive)
+ else O_DEC(opt, "edns-tcp-keepalive-timeout", tcp_keepalive_timeout)
else O_YNO(opt, "ssl-upstream", ssl_upstream)
else O_STR(opt, "ssl-service-key", ssl_service_key)
else O_STR(opt, "ssl-service-pem", ssl_service_pem)
int outgoing_tcp_mss;
/** tcp idle timeout */
int tcp_idle_timeout;
+ /** do edns tcp keepalive */
+ int do_tcp_keepalive;
+ /** tcp keepalive timeout */
+ int tcp_keepalive_timeout;
/** private key file for dnstcp-ssl service (enabled if not NULL) */
char* ssl_service_key;
tcp-mss{COLON} { YDVAR(1, VAR_TCP_MSS) }
outgoing-tcp-mss{COLON} { YDVAR(1, VAR_OUTGOING_TCP_MSS) }
tcp-idle-timeout{COLON} { YDVAR(1, VAR_TCP_IDLE_TIMEOUT) }
+edns-tcp-keepalive{COLON} { YDVAR(1, VAR_EDNS_TCP_KEEPALIVE) }
+edns-tcp-keepalive-timeout{COLON} { YDVAR(1, VAR_EDNS_TCP_KEEPALIVE_TIMEOUT) }
ssl-upstream{COLON} { YDVAR(1, VAR_SSL_UPSTREAM) }
tls-upstream{COLON} { YDVAR(1, VAR_SSL_UPSTREAM) }
ssl-service-key{COLON} { YDVAR(1, VAR_SSL_SERVICE_KEY) }
%token VAR_OUTGOING_RANGE VAR_INTERFACE
%token VAR_DO_IP4 VAR_DO_IP6 VAR_PREFER_IP6 VAR_DO_UDP VAR_DO_TCP
%token VAR_TCP_MSS VAR_OUTGOING_TCP_MSS VAR_TCP_IDLE_TIMEOUT
+%token VAR_EDNS_TCP_KEEPALIVE VAR_EDNS_TCP_KEEPALIVE_TIMEOUT
%token VAR_CHROOT VAR_USERNAME VAR_DIRECTORY VAR_LOGFILE VAR_PIDFILE
%token VAR_MSG_CACHE_SIZE VAR_MSG_CACHE_SLABS VAR_NUM_QUERIES_PER_THREAD
%token VAR_RRSET_CACHE_SIZE VAR_RRSET_CACHE_SLABS VAR_OUTGOING_NUM_TCP
server_do_ip6 | server_prefer_ip6 |
server_do_udp | server_do_tcp |
server_tcp_mss | server_outgoing_tcp_mss | server_tcp_idle_timeout |
+ server_tcp_keepalive | server_tcp_keepalive_timeout |
server_interface | server_chroot | server_username |
server_directory | server_logfile | server_pidfile |
server_msg_cache_size | server_msg_cache_slabs |
free($2);
}
;
+server_tcp_keepalive: VAR_EDNS_TCP_KEEPALIVE STRING_ARG
+ {
+ OUTYY(("P(server_tcp_keepalive:%s)\n", $2));
+ if(strcmp($2, "yes") != 0 && strcmp($2, "no") != 0)
+ yyerror("expected yes or no.");
+ else cfg_parser->cfg->do_tcp_keepalive = (strcmp($2, "yes")==0);
+ free($2);
+ }
+ ;
+server_tcp_keepalive_timeout: VAR_EDNS_TCP_KEEPALIVE_TIMEOUT STRING_ARG
+ {
+ OUTYY(("P(server_tcp_keepalive_timeout:%s)\n", $2));
+ if(atoi($2) == 0 && strcmp($2, "0") != 0)
+ yyerror("number expected");
+ else if (atoi($2) > 6553500)
+ cfg_parser->cfg->tcp_keepalive_timeout = 6553500;
+ else if (atoi($2) < 1)
+ cfg_parser->cfg->tcp_keepalive_timeout = 0;
+ else cfg_parser->cfg->tcp_keepalive_timeout = atoi($2);
+ free($2);
+ }
+ ;
server_tcp_upstream: VAR_TCP_UPSTREAM STRING_ARG
{
OUTYY(("P(server_tcp_upstream:%s)\n", $2));
#define TCP_QUERY_TIMEOUT 120000
/** The TCP timeout in msec for fast queries, above half are used */
#define TCP_QUERY_TIMEOUT_FAST 200
+/** The minimum actual TCP timeout to use, regardless of what we advertise */
+#define TCP_QUERY_TIMEOUT_MINIMUM 200
#ifndef NONBLOCKING_IS_BROKEN
/** number of UDP reads to perform per read indication from select */
* timeout for this TCP connection, we need to make space for
* other connections to be able to get attention */
if(cur > max/2)
- c->tcp_timeout_msec = TCP_QUERY_TIMEOUT_FAST;
- comm_point_start_listening(c, fd, c->tcp_timeout_msec);
+ c->tcp_timeout_msec = 0;
+ comm_point_start_listening(c, fd,
+ c->tcp_timeout_msec < TCP_QUERY_TIMEOUT_MINIMUM
+ ? TCP_QUERY_TIMEOUT_MINIMUM
+ : c->tcp_timeout_msec);
}
void comm_base_handle_slow_accept(int ATTR_UNUSED(fd),
c->tcp_byte_count = 0;
c->tcp_parent = parent;
c->tcp_timeout_msec = parent->tcp_timeout_msec;
+ c->tcp_keepalive = 0;
c->max_tcp_count = 0;
c->cur_tcp_count = 0;
c->tcp_handlers = NULL;
c->tcp_is_reading = 0;
c->tcp_byte_count = 0;
c->tcp_timeout_msec = idle_timeout;
+ c->tcp_keepalive = 0;
c->tcp_parent = NULL;
c->max_tcp_count = num;
c->cur_tcp_count = 0;
c->tcp_is_reading = 0;
c->tcp_byte_count = 0;
c->tcp_timeout_msec = TCP_QUERY_TIMEOUT;
+ c->tcp_keepalive = 0;
c->tcp_parent = NULL;
c->max_tcp_count = 0;
c->cur_tcp_count = 0;
/** timeout in msec for TCP wait times for this connection */
int tcp_timeout_msec;
+ /** if set, tcp keepalive is enabled on this connection */
+ int tcp_keepalive;
+
/** if set, checks for pending error from nonblocking connect() call.*/
int tcp_check_nb_connect;