]> git.ipfire.org Git - thirdparty/unbound.git/commitdiff
- Sort out test runs when the build directory isn't the project
authorWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 31 Jul 2018 07:15:12 +0000 (07:15 +0000)
committerWouter Wijngaards <wouter@nlnetlabs.nl>
Tue, 31 Jul 2018 07:15:12 +0000 (07:15 +0000)
  root directory.
- Add config tcp-idle-timeout (default 30s). This applies to
  client connections only; the timeout on TCP connections upstream
  is unaffected.

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

23 files changed:
Makefile.in
daemon/worker.c
doc/Changelog
doc/unbound.conf.5.in
services/listen_dnsport.c
services/listen_dnsport.h
testcode/fake_event.c
testcode/streamtcp.c
testcode/unitldns.c
testcode/unitmsgparse.c
testcode/unitverify.c
testdata/tcp_idle_timeout.tdir/tcp_idle_timeout.conf [new file with mode: 0644]
testdata/tcp_idle_timeout.tdir/tcp_idle_timeout.dsc [new file with mode: 0644]
testdata/tcp_idle_timeout.tdir/tcp_idle_timeout.post [new file with mode: 0644]
testdata/tcp_idle_timeout.tdir/tcp_idle_timeout.pre [new file with mode: 0644]
testdata/tcp_idle_timeout.tdir/tcp_idle_timeout.test [new file with mode: 0644]
testdata/tcp_idle_timeout.tdir/tcp_idle_timeout.testns [new file with mode: 0644]
util/config_file.c
util/config_file.h
util/configlexer.lex
util/configparser.y
util/netevent.c
util/netevent.h

index aa620b2050520b1e058ecd10fd1f4add4fa647b5..40be553274e7dbbc357f1560bbc58119c15616e9 100644 (file)
@@ -57,7 +57,7 @@ STRIP=@STRIP@
 CC=@CC@
 CPPFLAGS=-I. @CPPFLAGS@
 PYTHON_CPPFLAGS=-I. @PYTHON_CPPFLAGS@
-CFLAGS=@CFLAGS@
+CFLAGS=-DSRCDIR=$(srcdir) @CFLAGS@
 LDFLAGS=@LDFLAGS@
 LIBS=@LIBS@
 LIBOBJS=@LIBOBJS@
@@ -306,10 +306,11 @@ longcheck: longtest
 test:  unittest$(EXEEXT) testbound$(EXEEXT)
        ./unittest$(EXEEXT)
        ./testbound$(EXEEXT) -s
-       for x in testdata/*.rpl; do echo -n "$$x "; if ./testbound$(EXEEXT) -p $$x >/dev/null 2>&1; then echo OK; else echo failed; exit 1; fi done
+       for x in $(srcdir)/testdata/*.rpl; do echo -n "$$x "; if ./testbound$(EXEEXT) -p $$x >/dev/null 2>&1; then echo OK; else echo failed; exit 1; fi done
        @echo test OK
 
 longtest:      tests
+       if test ! $(srcdir)/testdata -ef ./testdata; then rm -rf testcode testdata; mkdir testcode testdata; cp -R $(srcdir)/testdata/*.sh $(srcdir)/testdata/*.tdir testdata; cp $(srcdir)/testcode/*.sh testcode; fi
        if test -x "`which bash`"; then bash testcode/do-tests.sh; else sh testcode/do-tests.sh; fi
 
 lib:   libunbound.la unbound.h
index 44a989a4e9458291b837aedf2a03e19e4f55e76c..8568ac3cf77627444150c1c1208a087dbce4a408 100644 (file)
@@ -1708,9 +1708,9 @@ worker_init(struct worker* worker, struct config_file *cfg,
                worker->comsig = NULL;
        }
        worker->front = listen_create(worker->base, ports,
-               cfg->msg_buffer_size, (int)cfg->incoming_num_tcp, 
-               worker->daemon->listen_sslctx, dtenv, worker_handle_request,
-               worker);
+               cfg->msg_buffer_size, (int)cfg->incoming_num_tcp,
+               cfg->tcp_idle_timeout, worker->daemon->listen_sslctx,
+               dtenv, worker_handle_request, worker);
        if(!worker->front) {
                log_err("could not create listening sockets");
                worker_delete(worker);
index 3e2cabc5ecc9b4767c36efa5db35fa89aa1ed560..08e4fca33041ef7a1b155d3676b4fa928fc2d119 100644 (file)
@@ -1,3 +1,16 @@
+31 July 2018: Wouter
+       - Patches from Jim Hague (Sinodun) for EDNS KeepAlive.
+       - Sort out test runs when the build directory isn't the project
+         root directory.
+       - Add config tcp-idle-timeout (default 30s). This applies to
+         client connections only; the timeout on TCP connections upstream
+         is unaffected.
+       - Error if EDNS Keepalive received over UDP.
+       - Add edns-tcp-keepalive and edns-tcp-keepalive timeout options
+         and implement option in client responses.
+       - Correct and expand manual page entries for keepalive and idle timeout.
+       - Implement progressive backoff of TCP idle/keepalive timeout.
+
 30 July 2018: Wouter
        - Fix #4136: insufficiency from mismatch of FLEX capability between
          released tarball and build host.
index e5c76b5f9a7ee45dd4655970b6a7f758e8bfd189..e41e9110071ea820f478abeb899236b6dfe8c8ea 100644 (file)
@@ -389,6 +389,11 @@ Note that not all platform supports socket option to set MSS (TCP_MAXSEG).
 Default is system default MSS determined by interface MTU and
 negotiation between Unbound and other servers.
 .TP
+.B tcp-idle-timeout: \fI<msec>\fR
+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 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 3d3c5cbe538533c0b5e38b884e0c6b1dbc83b2f8..5cae35ec88afa9db12af78cb8ce1f2ae9c45e44a 100644 (file)
@@ -1227,8 +1227,9 @@ listen_cp_insert(struct comm_point* c, struct listen_dnsport* front)
 
 struct listen_dnsport* 
 listen_create(struct comm_base* base, struct listen_port* ports,
-       size_t bufsize, int tcp_accept_count, void* sslctx,
-       struct dt_env* dtenv, comm_point_callback_type* cb, void *cb_arg)
+       size_t bufsize, int tcp_accept_count, int tcp_idle_timeout,
+       void* sslctx, struct dt_env* dtenv,
+       comm_point_callback_type* cb, void *cb_arg)
 {
        struct listen_dnsport* front = (struct listen_dnsport*)
                malloc(sizeof(struct listen_dnsport));
@@ -1254,10 +1255,12 @@ listen_create(struct comm_base* base, struct listen_port* ports,
                else if(ports->ftype == listen_type_tcp ||
                                ports->ftype == listen_type_tcp_dnscrypt)
                        cp = comm_point_create_tcp(base, ports->fd, 
-                               tcp_accept_count, bufsize, cb, cb_arg);
+                               tcp_accept_count, tcp_idle_timeout,
+                               bufsize, cb, cb_arg);
                else if(ports->ftype == listen_type_ssl) {
                        cp = comm_point_create_tcp(base, ports->fd, 
-                               tcp_accept_count, bufsize, cb, cb_arg);
+                               tcp_accept_count, tcp_idle_timeout,
+                               bufsize, cb, cb_arg);
                        cp->ssl = sslctx;
                } else if(ports->ftype == listen_type_udpancil ||
                                  ports->ftype == listen_type_udpancil_dnscrypt)
index fac0f79709245cab5b46cf07617de9a0b2db9d1f..d97cfc7c2c08565a99b9918d19f6f2de8e191914 100644 (file)
@@ -145,7 +145,8 @@ void listening_ports_free(struct listen_port* list);
  * @return: the malloced listening structure, ready for use. NULL on error.
  */
 struct listen_dnsport* listen_create(struct comm_base* base,
-       struct listen_port* ports, size_t bufsize, int tcp_accept_count,
+       struct listen_port* ports, size_t bufsize,
+       int tcp_accept_count, int tcp_idle_timeout,
        void* sslctx, struct dt_env *dtenv, comm_point_callback_type* cb,
        void* cb_arg);
 
index 80e3685c09efa8ca2d313ec95f3d168a067db4d0..f192c0368cc01e6e2302b5afc258fa7f43985e46 100644 (file)
@@ -856,6 +856,7 @@ run_scenario(struct replay_runtime* runtime)
 struct listen_dnsport* 
 listen_create(struct comm_base* base, struct listen_port* ATTR_UNUSED(ports),
        size_t bufsize, int ATTR_UNUSED(tcp_accept_count),
+       int ATTR_UNUSED(tcp_idle_timeout),
        void* ATTR_UNUSED(sslctx), struct dt_env* ATTR_UNUSED(dtenv),
        comm_point_callback_type* cb, void* cb_arg)
 {
index 0a636395fd35c1bbdf9f706e96e3271c381aea06..ce335f6c8525a925caa9ce271dbecc98e0170629 100644 (file)
@@ -44,6 +44,8 @@
 #include <getopt.h>
 #endif
 #include <signal.h>
+#include <stdlib.h>
+#include <unistd.h>
 #include "util/locks.h"
 #include "util/log.h"
 #include "util/net_help.h"
@@ -71,6 +73,7 @@ static void usage(char* argv[])
        printf("-f server       what ipaddr@portnr to send the queries to\n");
        printf("-u              use UDP. No retries are attempted.\n");
        printf("-n              do not wait for an answer.\n");
+       printf("-d secs         delay after connection before sending query\n");
        printf("-s              use ssl\n");
        printf("-h              this help text\n");
        exit(1);
@@ -275,7 +278,8 @@ static int get_random(void)
 
 /** send the TCP queries and print answers */
 static void
-send_em(const char* svr, int udp, int usessl, int noanswer, int num, char** qs)
+send_em(const char* svr, int udp, int usessl, int noanswer, int delay,
+       int num, char** qs)
 {
        sldns_buffer* buf = sldns_buffer_new(65553);
        int fd = open_svr(svr, udp);
@@ -310,6 +314,8 @@ send_em(const char* svr, int udp, int usessl, int noanswer, int num, char** qs)
                }
        }
        for(i=0; i<num; i+=3) {
+               if (delay != 0)
+                       sleep(delay);
                printf("\nNext query is %s %s %s\n", qs[i], qs[i+1], qs[i+2]);
                write_q(fd, udp, ssl, buf, (uint16_t)get_random(), qs[i],
                        qs[i+1], qs[i+2]);
@@ -358,6 +364,7 @@ int main(int argc, char** argv)
        int udp = 0;
        int noanswer = 0;
        int usessl = 0;
+       int delay = 0;
 
 #ifdef USE_WINSOCK
        WSADATA wsa_data;
@@ -382,7 +389,7 @@ int main(int argc, char** argv)
        if(argc == 1) {
                usage(argv);
        }
-       while( (c=getopt(argc, argv, "f:hnsu")) != -1) {
+       while( (c=getopt(argc, argv, "f:hnsud:")) != -1) {
                switch(c) {
                        case 'f':
                                svr = optarg;
@@ -396,6 +403,13 @@ int main(int argc, char** argv)
                        case 's':
                                usessl = 1;
                                break;
+                       case 'd':
+                               if(atoi(optarg)==0 && strcmp(optarg,"0")!=0) {
+                                       printf("bad delay: %s\n", optarg);
+                                       return 1;
+                               }
+                               delay = atoi(optarg);
+                               break;
                        case 'h':
                        case '?':
                        default:
@@ -426,7 +440,7 @@ int main(int argc, char** argv)
                (void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
 #endif
        }
-       send_em(svr, udp, usessl, noanswer, argc, argv);
+       send_em(svr, udp, usessl, noanswer, delay, argc, argv);
        checklock_stop();
 #ifdef USE_WINSOCK
        WSACleanup();
index e27e46eaa9267ddfe9f0e550c913789bb18e10a3..66f75617037de92473463017fab99019643b80a8 100644 (file)
@@ -199,15 +199,25 @@ rr_test_file(const char* input, const char* check)
        free(back);
 }
 
+#define xstr(s) str(s)
+#define str(s) #s
+
+#define SRCDIRSTR xstr(SRCDIR)
+
 /** read rrs to and from string, to and from wireformat */
 static void
 rr_tests(void)
 {
-       rr_test_file("testdata/test_ldnsrr.1", "testdata/test_ldnsrr.c1");
-       rr_test_file("testdata/test_ldnsrr.2", "testdata/test_ldnsrr.c2");
-       rr_test_file("testdata/test_ldnsrr.3", "testdata/test_ldnsrr.c3");
-       rr_test_file("testdata/test_ldnsrr.4", "testdata/test_ldnsrr.c4");
-       rr_test_file("testdata/test_ldnsrr.5", "testdata/test_ldnsrr.c5");
+       rr_test_file(SRCDIRSTR "/testdata/test_ldnsrr.1",
+               SRCDIRSTR "/testdata/test_ldnsrr.c1");
+       rr_test_file(SRCDIRSTR "/testdata/test_ldnsrr.2",
+               SRCDIRSTR "/testdata/test_ldnsrr.c2");
+       rr_test_file(SRCDIRSTR "/testdata/test_ldnsrr.3",
+               SRCDIRSTR "/testdata/test_ldnsrr.c3");
+       rr_test_file(SRCDIRSTR "/testdata/test_ldnsrr.4",
+               SRCDIRSTR "/testdata/test_ldnsrr.c4");
+       rr_test_file(SRCDIRSTR "/testdata/test_ldnsrr.5",
+               SRCDIRSTR "/testdata/test_ldnsrr.c5");
 }
 
 void
index 627d10b78ec3dd5148b3b051931e6e9403ce4e5e..c0b38bac76e4f0f42f5cf470f24a838707a1d702 100644 (file)
@@ -495,6 +495,11 @@ testfromdrillfile(sldns_buffer* pkt, struct alloc_cache* alloc,
        fclose(in);
 }
 
+#define xstr(s) str(s)
+#define str(s) #s
+
+#define SRCDIRSTR xstr(SRCDIR)
+
 void msgparse_test(void)
 {
        time_t origttl = MAX_NEG_TTL;
@@ -509,27 +514,27 @@ void msgparse_test(void)
        unit_show_feature("message parse");
        simpletest(pkt, &alloc, out);
        /* plain hex dumps, like pcat */
-       testfromfile(pkt, &alloc, out, "testdata/test_packets.1");
-       testfromfile(pkt, &alloc, out, "testdata/test_packets.2");
-       testfromfile(pkt, &alloc, out, "testdata/test_packets.3");
+       testfromfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.1");
+       testfromfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.2");
+       testfromfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.3");
        /* like from drill -w - */
-       testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.4");
-       testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.5");
+       testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.4");
+       testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.5");
 
        matches_nolocation = 1; /* RR order not important for the next test */
-       testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.6");
+       testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.6");
        check_rrsigs = 1;
-       testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.7");
+       testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.7");
        check_rrsigs = 0;
        matches_nolocation = 0; 
 
        check_formerr_gone = 1;
-       testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.8");
+       testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.8");
        check_formerr_gone = 0;
 
        check_rrsigs = 1;
        check_nosameness = 1;
-       testfromdrillfile(pkt, &alloc, out, "testdata/test_packets.9");
+       testfromdrillfile(pkt, &alloc, out, SRCDIRSTR "/testdata/test_packets.9");
        check_nosameness = 0;
        check_rrsigs = 0;
 
index 95676e10490559b4dc5ef2f763ec9f99584be2c7..9e101324960e50989e8919ad8b279d58452cd88b 100644 (file)
@@ -497,65 +497,70 @@ nsec3_hash_test(const char* fname)
        sldns_buffer_free(buf);
 }
 
+#define xstr(s) str(s)
+#define str(s) #s
+
+#define SRCDIRSTR xstr(SRCDIR)
+
 void 
 verify_test(void)
 {
        unit_show_feature("signature verify");
 #ifdef USE_SHA1
-       verifytest_file("testdata/test_signatures.1", "20070818005004");
+       verifytest_file(SRCDIRSTR "/testdata/test_signatures.1", "20070818005004");
 #endif
 #if defined(USE_DSA) && defined(USE_SHA1)
-       verifytest_file("testdata/test_signatures.2", "20080414005004");
-       verifytest_file("testdata/test_signatures.3", "20080416005004");
-       verifytest_file("testdata/test_signatures.4", "20080416005004");
-       verifytest_file("testdata/test_signatures.5", "20080416005004");
-       verifytest_file("testdata/test_signatures.6", "20080416005004");
-       verifytest_file("testdata/test_signatures.7", "20070829144150");
+       verifytest_file(SRCDIRSTR "/testdata/test_signatures.2", "20080414005004");
+       verifytest_file(SRCDIRSTR "/testdata/test_signatures.3", "20080416005004");
+       verifytest_file(SRCDIRSTR "/testdata/test_signatures.4", "20080416005004");
+       verifytest_file(SRCDIRSTR "/testdata/test_signatures.5", "20080416005004");
+       verifytest_file(SRCDIRSTR "/testdata/test_signatures.6", "20080416005004");
+       verifytest_file(SRCDIRSTR "/testdata/test_signatures.7", "20070829144150");
 #endif /* USE_DSA */
 #ifdef USE_SHA1
-       verifytest_file("testdata/test_signatures.8", "20070829144150");
+       verifytest_file(SRCDIRSTR "/testdata/test_signatures.8", "20070829144150");
 #endif
 #if (defined(HAVE_EVP_SHA256) || defined(HAVE_NSS) || defined(HAVE_NETTLE)) && defined(USE_SHA2)
-       verifytest_file("testdata/test_sigs.rsasha256", "20070829144150");
+       verifytest_file(SRCDIRSTR "/testdata/test_sigs.rsasha256", "20070829144150");
 #  ifdef USE_SHA1
-       verifytest_file("testdata/test_sigs.sha1_and_256", "20070829144150");
+       verifytest_file(SRCDIRSTR "/testdata/test_sigs.sha1_and_256", "20070829144150");
 #  endif
-       verifytest_file("testdata/test_sigs.rsasha256_draft", "20090101000000");
+       verifytest_file(SRCDIRSTR "/testdata/test_sigs.rsasha256_draft", "20090101000000");
 #endif
 #if (defined(HAVE_EVP_SHA512) || defined(HAVE_NSS) || defined(HAVE_NETTLE)) && defined(USE_SHA2)
-       verifytest_file("testdata/test_sigs.rsasha512_draft", "20070829144150");
-       verifytest_file("testdata/test_signatures.9", "20171215000000");
+       verifytest_file(SRCDIRSTR "/testdata/test_sigs.rsasha512_draft", "20070829144150");
+       verifytest_file(SRCDIRSTR "/testdata/test_signatures.9", "20171215000000");
 #endif
 #ifdef USE_SHA1
-       verifytest_file("testdata/test_sigs.hinfo", "20090107100022");
-       verifytest_file("testdata/test_sigs.revoked", "20080414005004");
+       verifytest_file(SRCDIRSTR "/testdata/test_sigs.hinfo", "20090107100022");
+       verifytest_file(SRCDIRSTR "/testdata/test_sigs.revoked", "20080414005004");
 #endif
 #ifdef USE_GOST
        if(sldns_key_EVP_load_gost_id())
-         verifytest_file("testdata/test_sigs.gost", "20090807060504");
+         verifytest_file(SRCDIRSTR "/testdata/test_sigs.gost", "20090807060504");
        else printf("Warning: skipped GOST, openssl does not provide gost.\n");
 #endif
 #ifdef USE_ECDSA
        /* test for support in case we use libNSS and ECC is removed */
        if(dnskey_algo_id_is_supported(LDNS_ECDSAP256SHA256)) {
-               verifytest_file("testdata/test_sigs.ecdsa_p256", "20100908100439");
-               verifytest_file("testdata/test_sigs.ecdsa_p384", "20100908100439");
+               verifytest_file(SRCDIRSTR "/testdata/test_sigs.ecdsa_p256", "20100908100439");
+               verifytest_file(SRCDIRSTR "/testdata/test_sigs.ecdsa_p384", "20100908100439");
        }
-       dstest_file("testdata/test_ds.sha384");
+       dstest_file(SRCDIRSTR "/testdata/test_ds.sha384");
 #endif
 #ifdef USE_ED25519
        if(dnskey_algo_id_is_supported(LDNS_ED25519)) {
-               verifytest_file("testdata/test_sigs.ed25519", "20170530140439");
+               verifytest_file(SRCDIRSTR "/testdata/test_sigs.ed25519", "20170530140439");
        }
 #endif
 #ifdef USE_ED448
        if(dnskey_algo_id_is_supported(LDNS_ED448)) {
-               verifytest_file("testdata/test_sigs.ed448", "20180408143630");
+               verifytest_file(SRCDIRSTR "/testdata/test_sigs.ed448", "20180408143630");
        }
 #endif
 #ifdef USE_SHA1
-       dstest_file("testdata/test_ds.sha1");
+       dstest_file(SRCDIRSTR "/testdata/test_ds.sha1");
 #endif
        nsectest();
-       nsec3_hash_test("testdata/test_nsec3_hash.1");
+       nsec3_hash_test(SRCDIRSTR "/testdata/test_nsec3_hash.1");
 }
diff --git a/testdata/tcp_idle_timeout.tdir/tcp_idle_timeout.conf b/testdata/tcp_idle_timeout.tdir/tcp_idle_timeout.conf
new file mode 100644 (file)
index 0000000..e778ca5
--- /dev/null
@@ -0,0 +1,16 @@
+server:
+       verbosity: 2
+       # num-threads: 1
+       interface: 127.0.0.1
+       port: @PORT@
+       use-syslog: no
+       directory: .
+       pidfile: "unbound.pid"
+       chroot: ""
+       username: ""
+       do-not-query-localhost: no
+       tcp-idle-timeout: 2
+
+forward-zone:
+       name: "."
+       forward-addr: "127.0.0.1@@TOPORT@"
diff --git a/testdata/tcp_idle_timeout.tdir/tcp_idle_timeout.dsc b/testdata/tcp_idle_timeout.tdir/tcp_idle_timeout.dsc
new file mode 100644 (file)
index 0000000..44edd52
--- /dev/null
@@ -0,0 +1,16 @@
+BaseName: tcp_idle_timeout
+Version: 1.0
+Description: Test tcp-idle-timeout setting.
+CreationDate: Thu Jul 12 13:55:00 BST 2018
+Maintainer: dr. J. Hague
+Category: 
+Component:
+CmdDepends: 
+Depends: 
+Help:
+Pre: tcp_idle_timeout.pre
+Post: tcp_idle_timeout.post
+Test: tcp_idle_timeout.test
+AuxFiles: 
+Passed:
+Failure:
diff --git a/testdata/tcp_idle_timeout.tdir/tcp_idle_timeout.post b/testdata/tcp_idle_timeout.tdir/tcp_idle_timeout.post
new file mode 100644 (file)
index 0000000..e851346
--- /dev/null
@@ -0,0 +1,10 @@
+# #-- tcp_idle_timeout.post --#
+# source the master var file when it's there
+[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
+# source the test var file when it's there
+[ -f .tpkg.var.test ] && source .tpkg.var.test
+#
+# do your teardown here
+. ../common.sh
+kill_pid $FWD_PID
+kill_pid $UNBOUND_PID
diff --git a/testdata/tcp_idle_timeout.tdir/tcp_idle_timeout.pre b/testdata/tcp_idle_timeout.tdir/tcp_idle_timeout.pre
new file mode 100644 (file)
index 0000000..d36319d
--- /dev/null
@@ -0,0 +1,31 @@
+# #-- tcp_idle_timeout.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
+FWD_PORT=$(($RND_PORT + 1))
+echo "UNBOUND_PORT=$UNBOUND_PORT" >> .tpkg.var.test
+echo "FWD_PORT=$FWD_PORT" >> .tpkg.var.test
+
+# start forwarder
+get_ldns_testns
+$LDNS_TESTNS -p $FWD_PORT tcp_idle_timeout.testns >fwd.log 2>&1 &
+FWD_PID=$!
+echo "FWD_PID=$FWD_PID" >> .tpkg.var.test
+
+# make config file
+sed -e 's/@PORT\@/'$UNBOUND_PORT'/' -e 's/@TOPORT\@/'$FWD_PORT'/' < tcp_idle_timeout.conf > ub.conf
+# start unbound in the background
+PRE="../.."
+$PRE/unbound -d -c ub.conf >unbound.log 2>&1 &
+UNBOUND_PID=$!
+echo "UNBOUND_PID=$UNBOUND_PID" >> .tpkg.var.test
+
+cat .tpkg.var.test
+wait_ldns_testns_up fwd.log
+wait_unbound_up unbound.log
+
diff --git a/testdata/tcp_idle_timeout.tdir/tcp_idle_timeout.test b/testdata/tcp_idle_timeout.tdir/tcp_idle_timeout.test
new file mode 100644 (file)
index 0000000..30852e0
--- /dev/null
@@ -0,0 +1,63 @@
+# #-- tcp_idle_timeout.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
+
+if uname | grep MINGW >/dev/null; then
+       echo "no job control in shell on windows. end test"
+       exit 0
+fi
+
+PRE="../.."
+. ../common.sh
+get_make
+(cd $PRE; $MAKE streamtcp)
+
+# first test a single TCP query with no delay.
+echo "> query www.example.com."
+$PRE/streamtcp -f 127.0.0.1@$UNBOUND_PORT www.example.com. A IN >outfile 2>&1
+if test "$?" -ne 0; then
+       echo "exit status not OK"
+       echo "> cat logfiles"
+       cat outfile
+       cat fwd.log 
+       cat unbound.log
+       echo "Not OK"
+       exit 1
+else
+       echo "exit status OK"
+fi
+echo "> cat logfiles"
+cat outfile
+cat fwd.log 
+cat unbound.log
+echo "> check answer"
+if grep "10.20.30.40" outfile; then
+       echo "OK"
+else
+       echo "Not OK"
+       exit 1
+fi
+
+# now test query with delay should fail.
+echo "> query www.example.com."
+$PRE/streamtcp -d 4 -f 127.0.0.1@$UNBOUND_PORT www.example.com. A IN >outfile 2>&1
+if test "$?" -eq 0; then
+       echo "exit status OK"
+       echo "> cat logfiles"
+       cat outfile
+       cat fwd.log 
+       cat unbound.log
+       echo "Not OK"
+       exit 1
+else
+       echo "exit status not OK"
+fi
+echo "> cat logfiles"
+cat outfile
+cat fwd.log 
+cat unbound.log
+echo "OK"
+
+exit 0
diff --git a/testdata/tcp_idle_timeout.tdir/tcp_idle_timeout.testns b/testdata/tcp_idle_timeout.tdir/tcp_idle_timeout.testns
new file mode 100644 (file)
index 0000000..1464772
--- /dev/null
@@ -0,0 +1,42 @@
+; nameserver test file
+$ORIGIN example.com.
+$TTL 3600
+
+ENTRY_BEGIN
+MATCH UDP opcode qtype qname
+REPLY QR AA NOERROR TC
+ADJUST copy_id 
+SECTION QUESTION
+www    IN      A
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH TCP opcode qtype qname
+REPLY QR AA NOERROR
+ADJUST copy_id sleep=2
+SECTION QUESTION
+www    IN      A
+SECTION ANSWER
+www    IN      A       10.20.30.40
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+REPLY QR AA NOERROR
+ADJUST copy_id
+SECTION QUESTION
+www2   IN      A
+SECTION ANSWER
+www2   IN      A       10.20.30.42
+ENTRY_END
+
+ENTRY_BEGIN
+MATCH opcode qtype qname
+REPLY QR AA NOERROR
+ADJUST copy_id
+SECTION QUESTION
+www3   IN      A
+SECTION ANSWER
+www3   IN      A       10.20.30.43
+ENTRY_END
+
index 694a8c6cebe81ae6b2cf8714ca6fe211fe3194e4..d5726432c53a0ed5551bea8ebc8c34bae65b47c8 100644 (file)
@@ -104,6 +104,7 @@ config_create(void)
        cfg->udp_upstream_without_downstream = 0;
        cfg->tcp_mss = 0;
        cfg->outgoing_tcp_mss = 0;
+       cfg->tcp_idle_timeout = 30 * 1000; /* 30s in millisecs */
        cfg->ssl_service_key = NULL;
        cfg->ssl_service_pem = NULL;
        cfg->ssl_port = UNBOUND_DNS_OVER_TLS_PORT;
@@ -455,6 +456,7 @@ int config_set_option(struct config_file* cfg, const char* opt,
                udp_upstream_without_downstream)
        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("ssl-upstream:", ssl_upstream)
        else S_STR("ssl-service-key:", ssl_service_key)
        else S_STR("ssl-service-pem:", ssl_service_pem)
@@ -878,6 +880,7 @@ config_get_option(struct config_file* cfg, const char* opt,
        else O_YNO(opt, "udp-upstream-without-downstream", udp_upstream_without_downstream)
        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, "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 7af0067f9b64e36fcb5fb6cd1dd4d8be69e06a26..c27595b741d1d833b35fc0ad0c08c91124809d04 100644 (file)
@@ -99,6 +99,8 @@ struct config_file {
        int tcp_mss;
        /** maximum segment size of tcp socket for outgoing queries */
        int outgoing_tcp_mss;
+       /** tcp idle timeout */
+       int tcp_idle_timeout;
 
        /** private key file for dnstcp-ssl service (enabled if not NULL) */
        char* ssl_service_key;
index 14aafbf7684a9f50c5af19c1f72ee84a4acfac06..dbad5eab20dd1f1222666b51fb892e16be1b96ac 100644 (file)
@@ -233,6 +233,7 @@ do-tcp{COLON}                       { YDVAR(1, VAR_DO_TCP) }
 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) }
 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 1c264bc6e676e28b852d623275f7f4f8a7ed88da..e60002f53debe18e28f32a72580383c3caf8c82d 100644 (file)
@@ -72,7 +72,7 @@ extern struct config_parser_state* cfg_parser;
 %token VAR_SERVER VAR_VERBOSITY VAR_NUM_THREADS VAR_PORT
 %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
+%token VAR_TCP_MSS VAR_OUTGOING_TCP_MSS VAR_TCP_IDLE_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
@@ -180,7 +180,7 @@ content_server: server_num_threads | server_verbosity | server_port |
        server_outgoing_range | server_do_ip4 |
        server_do_ip6 | server_prefer_ip6 |
        server_do_udp | server_do_tcp |
-       server_tcp_mss | server_outgoing_tcp_mss |
+       server_tcp_mss | server_outgoing_tcp_mss | server_tcp_idle_timeout |
        server_interface | server_chroot | server_username | 
        server_directory | server_logfile | server_pidfile |
        server_msg_cache_size | server_msg_cache_slabs |
@@ -631,6 +631,19 @@ server_outgoing_tcp_mss: VAR_OUTGOING_TCP_MSS STRING_ARG
                free($2);
        }
        ;
+server_tcp_idle_timeout: VAR_TCP_IDLE_TIMEOUT STRING_ARG
+       {
+               OUTYY(("P(server_tcp_idle_timeout:%s)\n", $2));
+               if(atoi($2) == 0 && strcmp($2, "0") != 0)
+                       yyerror("number expected");
+               else if (atoi($2) > 120000)
+                       cfg_parser->cfg->tcp_idle_timeout = 120000;
+               else if (atoi($2) < 1)
+                       cfg_parser->cfg->tcp_idle_timeout = 1;
+               else cfg_parser->cfg->tcp_idle_timeout = atoi($2);
+               free($2);
+       }
+       ;
 server_tcp_upstream: VAR_TCP_UPSTREAM STRING_ARG
        {
                OUTYY(("P(server_tcp_upstream:%s)\n", $2));
index 5cc8606fad3e66e10e9820d1b2231f746e8856aa..49d52a349086a25a011140be9e954fd022280a80 100644 (file)
@@ -82,7 +82,7 @@
 #  endif
 #endif
 
-/** The TCP reading or writing query timeout in milliseconds */
+/** The TCP writing query timeout in milliseconds */
 #define TCP_QUERY_TIMEOUT 120000
 /** The TCP timeout in msec for fast queries, above half are used */
 #define TCP_QUERY_TIMEOUT_FAST 200
@@ -737,7 +737,6 @@ setup_tcp_handler(struct comm_point* c, int fd, int cur, int max)
 #endif
        c->tcp_is_reading = 1;
        c->tcp_byte_count = 0;
-       c->tcp_timeout_msec = TCP_QUERY_TIMEOUT;
        /* if more than half the tcp handlers are in use, use a shorter
         * timeout for this TCP connection, we need to make space for
         * other connections to be able to get attention */
@@ -2525,6 +2524,7 @@ comm_point_create_tcp_handler(struct comm_base *base,
        c->tcp_is_reading = 0;
        c->tcp_byte_count = 0;
        c->tcp_parent = parent;
+       c->tcp_timeout_msec = parent->tcp_timeout_msec;
        c->max_tcp_count = 0;
        c->cur_tcp_count = 0;
        c->tcp_handlers = NULL;
@@ -2565,7 +2565,8 @@ comm_point_create_tcp_handler(struct comm_base *base,
 }
 
 struct comm_point* 
-comm_point_create_tcp(struct comm_base *base, int fd, int num, size_t bufsize,
+comm_point_create_tcp(struct comm_base *base, int fd, int num,
+       int idle_timeout, size_t bufsize,
         comm_point_callback_type* callback, void* callback_arg)
 {
        struct comm_point* c = (struct comm_point*)calloc(1,
@@ -2587,6 +2588,7 @@ comm_point_create_tcp(struct comm_base *base, int fd, int num, size_t bufsize,
        c->timeout = NULL;
        c->tcp_is_reading = 0;
        c->tcp_byte_count = 0;
+       c->tcp_timeout_msec = idle_timeout;
        c->tcp_parent = NULL;
        c->max_tcp_count = num;
        c->cur_tcp_count = 0;
@@ -2665,6 +2667,7 @@ comm_point_create_tcp_out(struct comm_base *base, size_t bufsize,
        c->timeout = NULL;
        c->tcp_is_reading = 0;
        c->tcp_byte_count = 0;
+       c->tcp_timeout_msec = TCP_QUERY_TIMEOUT;
        c->tcp_parent = NULL;
        c->max_tcp_count = 0;
        c->cur_tcp_count = 0;
index 6819f57f8d9e4f9abc2526a3b113776eee4d236e..921a05e43864e925907d855ce980af0aaab4441a 100644 (file)
@@ -443,6 +443,7 @@ struct comm_point* comm_point_create_udp_ancil(struct comm_base* base,
  * @param fd: file descriptor of open TCP socket set to listen nonblocking.
  * @param num: becomes max_tcp_count, the routine allocates that
  *     many tcp handler commpoints.
+ * @param idle_timeout: TCP idle timeout in ms.
  * @param bufsize: size of buffer to create for handlers.
  * @param callback: callback function pointer for TCP handlers.
  * @param callback_arg: will be passed to your callback function.
@@ -452,7 +453,7 @@ struct comm_point* comm_point_create_udp_ancil(struct comm_base* base,
  * Inits timeout to NULL. All handlers are on the free list.
  */
 struct comm_point* comm_point_create_tcp(struct comm_base* base,
-       int fd, int num, size_t bufsize, 
+       int fd, int num, int idle_timeout, size_t bufsize, 
        comm_point_callback_type* callback, void* callback_arg);
 
 /**