]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Add edns-tcp-keepalive and edns-tcp-keepalive timeout options
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 31 Jul 2018 07:18:34 +0000 (07:18 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 31 Jul 2018 07:18:34 +0000 (07:18 +0000)
  and implement option in client responses.

git-svn-id: file:///svn/unbound/trunk@4804 be551aaa-1e26-0410-a405-d3ace91eadb9

13 files changed:
Makefile.in
daemon/worker.c
doc/unbound.conf.5.in
services/mesh.c
testcode/fake_event.c
testcode/replay.h
testdata/edns_keepalive.rpl
util/config_file.c
util/config_file.h
util/configlexer.lex
util/configparser.y
util/netevent.c
util/netevent.h

index 40be553274e7dbbc357f1560bbc58119c15616e9..9f8ad1f94a214dc186a07d282da48a34c4ad5cd9 100644 (file)
@@ -115,7 +115,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/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 \
@@ -131,7 +131,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 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 \
@@ -1426,101 +1426,138 @@ libworker.lo libworker.o: $(srcdir)/libunbound/libworker.c config.h \
  $(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
index 7aa6ebe4271c3fd96c5502a1ed65094aac1d8221..4c88f048b917cfae0a2560950070a7995d94f80a 100644 (file)
@@ -66,6 +66,7 @@
 #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"
@@ -477,6 +478,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
         * 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;
@@ -534,6 +536,7 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
                }
        }
        /* 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;
@@ -542,7 +545,9 @@ answer_norec_from_cache(struct worker* worker, struct query_info* qinfo,
                (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,
@@ -614,6 +619,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
        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;
@@ -695,6 +701,7 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
                }
        } else  secure = 0;
 
+       edns_bak = *edns;
        edns->edns_version = EDNS_ADVERTISED_VERSION;
        edns->udp_size = EDNS_ADVERTISED_SIZE;
        edns->ext_rcode = 0;
@@ -728,7 +735,9 @@ answer_from_cache(struct worker* worker, struct query_info* qinfo,
                        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,
@@ -1272,9 +1281,9 @@ worker_handle_request(struct comm_point* c, void* arg, int error,
                        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;
@@ -1732,7 +1741,10 @@ worker_init(struct worker* worker, struct config_file *cfg,
        }
        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");
index e41e9110071ea820f478abeb899236b6dfe8c8ea..ff0554c1bcfd1aa6a1b5a991e7fee08acde79f9d 100644 (file)
@@ -394,6 +394,17 @@ The period Unbound will wait for a query on a TCP connection.
 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.
index 41aba74ab260765a902e34c384f68f8200597e63..43f481c25e692314fdc7112bd3b11440e9680b46 100644 (file)
@@ -55,6 +55,7 @@
 #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"
@@ -1100,6 +1101,9 @@ mesh_send_reply(struct mesh_state* m, int rcode, struct reply_info* rep,
                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, 
index f192c0368cc01e6e2302b5afc258fa7f43985e46..4bec88fed7b2067541e849161799025b38b11d16 100644 (file)
@@ -374,8 +374,11 @@ answer_callback_from_entry(struct replay_runtime* runtime,
        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;
@@ -423,6 +426,8 @@ answer_check_it(struct replay_runtime* runtime)
                        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 {
@@ -452,9 +457,12 @@ fake_front_query(struct replay_runtime* runtime, struct replay_moment *todo)
        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,
@@ -488,8 +496,11 @@ fake_pending_callback(struct replay_runtime* runtime,
        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);
index 81f0a2c275b22454e6a50ca40b8c59510fe2e07a..0cce0b4901057c955d7cf58fe165a43f70b140b6 100644 (file)
@@ -303,6 +303,9 @@ struct replay_runtime {
        /** 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 */
index a59f10ce1ccc973a2979db06f9e789cc3b1bf02f..9d00b6cf762a95f953f6ad3637f3bed8eb527d1d 100644 (file)
@@ -1,5 +1,7 @@
 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.
@@ -79,6 +81,45 @@ STEP 30 CHECK_ANSWER
         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
 
index d5726432c53a0ed5551bea8ebc8c34bae65b47c8..3f4c3c3f369dfdc0f75adaef9e7ab05d0d0579ad 100644 (file)
@@ -105,6 +105,8 @@ config_create(void)
        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;
@@ -457,6 +459,8 @@ int config_set_option(struct config_file* cfg, const char* opt,
        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)
@@ -881,6 +885,8 @@ config_get_option(struct config_file* cfg, const char* opt,
        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)
index c27595b741d1d833b35fc0ad0c08c91124809d04..062dc348bf7ed66d9ac611851a901b127201cbd5 100644 (file)
@@ -101,6 +101,10 @@ struct config_file {
        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;
index dbad5eab20dd1f1222666b51fb892e16be1b96ac..fc5c30a2fe646cb4854e3208d55be6ededae2153 100644 (file)
@@ -234,6 +234,8 @@ tcp-upstream{COLON}         { YDVAR(1, VAR_TCP_UPSTREAM) }
 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) }
index e60002f53debe18e28f32a72580383c3caf8c82d..8d3eb3bc974aeee23f2ce91e85c29f0b79d6d788 100644 (file)
@@ -73,6 +73,7 @@ extern struct config_parser_state* cfg_parser;
 %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
@@ -181,6 +182,7 @@ content_server: server_num_threads | server_verbosity | server_port |
        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 |
@@ -644,6 +646,28 @@ server_tcp_idle_timeout: VAR_TCP_IDLE_TIMEOUT STRING_ARG
                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));
index 49d52a349086a25a011140be9e954fd022280a80..d5ed0dfc8d57e1e9683408c428b95524eb8516e5 100644 (file)
@@ -86,6 +86,8 @@
 #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 */
@@ -741,8 +743,11 @@ setup_tcp_handler(struct comm_point* c, int fd, int cur, int max)
         * 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),
@@ -2525,6 +2530,7 @@ comm_point_create_tcp_handler(struct comm_base *base,
        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;
@@ -2589,6 +2595,7 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num,
        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;
@@ -2668,6 +2675,7 @@ comm_point_create_tcp_out(struct comm_base *base, size_t bufsize,
        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;
index 921a05e43864e925907d855ce980af0aaab4441a..3382a530c2a7bae988f5d7275aa4562759f3b63b 100644 (file)
@@ -256,6 +256,9 @@ struct comm_point {
        /** 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;