From ae9fe1a10ea265f8ef47ca5a331d29fd7218aaf4 Mon Sep 17 00:00:00 2001 From: Wouter Wijngaards Date: Mon, 14 Jan 2019 15:52:50 +0000 Subject: [PATCH] - streamtcp option -a send queries consecutively and prints answers as they arrive. - Fix for out of order processing administration quit cleanup. - unit test for tcp out of order processing. git-svn-id: file:///svn/unbound/trunk@5033 be551aaa-1e26-0410-a405-d3ace91eadb9 --- doc/Changelog | 6 + services/listen_dnsport.c | 9 +- services/mesh.c | 8 +- testcode/streamtcp.1 | 5 + testcode/streamtcp.c | 69 +++- .../tcp_req_order.tdir/tcp_req_order.conf | 22 ++ testdata/tcp_req_order.tdir/tcp_req_order.dsc | 16 + .../tcp_req_order.tdir/tcp_req_order.post | 11 + testdata/tcp_req_order.tdir/tcp_req_order.pre | 31 ++ .../tcp_req_order.tdir/tcp_req_order.test | 341 ++++++++++++++++++ .../tcp_req_order.tdir/tcp_req_order.testns | 74 ++++ 11 files changed, 578 insertions(+), 14 deletions(-) create mode 100644 testdata/tcp_req_order.tdir/tcp_req_order.conf create mode 100644 testdata/tcp_req_order.tdir/tcp_req_order.dsc create mode 100644 testdata/tcp_req_order.tdir/tcp_req_order.post create mode 100644 testdata/tcp_req_order.tdir/tcp_req_order.pre create mode 100644 testdata/tcp_req_order.tdir/tcp_req_order.test create mode 100644 testdata/tcp_req_order.tdir/tcp_req_order.testns diff --git a/doc/Changelog b/doc/Changelog index 45e187e4..2959b7f0 100644 --- a/doc/Changelog +++ b/doc/Changelog @@ -1,3 +1,9 @@ +14 January 2018: Wouter + - streamtcp option -a send queries consecutively and prints answers + as they arrive. + - Fix for out of order processing administration quit cleanup. + - unit test for tcp out of order processing. + 11 January 2018: Wouter - Initial commit for out-of-order processing for TCP and TLS. diff --git a/services/listen_dnsport.c b/services/listen_dnsport.c index 311cf2dd..9cfc65b6 100644 --- a/services/listen_dnsport.c +++ b/services/listen_dnsport.c @@ -72,6 +72,9 @@ /** number of queued TCP connections for listen() */ #define TCP_BACKLOG 256 +/** number of simultaneous requests a client can have */ +#define TCP_MAX_REQ_SIMULTANEOUS 32 + /** * Debug print of the getaddrinfo returned address. * @param addr: the address returned. @@ -1591,9 +1594,6 @@ tcp_req_info_remove_mesh_state(struct tcp_req_info* req, struct mesh_state* m) } } -/** number of simultaneous requests a client can have */ -#define TCP_MAX_REQ_SIMULTANEOUS 10 - /** setup listening for read or write */ static void tcp_req_info_setup_listen(struct tcp_req_info* req) @@ -1669,13 +1669,16 @@ int tcp_req_info_handle_read_close(struct tcp_req_info* req) { verbose(VERB_ALGO, "tcp channel read side closed %d", req->cp->fd); + /* if we still have results to write, pick up next and write it */ if(req->num_done_req != 0) { tcp_req_pickup_next_result(req); tcp_req_info_setup_listen(req); return 1; } + /* if nothing to do, this closes the connection */ if(req->num_open_req == 0 && req->num_done_req == 0) return 0; + /* otherwise, we must be waiting for dns resolve, wait with timeout */ req->read_is_closed = 1; tcp_req_info_setup_listen(req); return 1; diff --git a/services/mesh.c b/services/mesh.c index 01771af3..5ffef771 100644 --- a/services/mesh.c +++ b/services/mesh.c @@ -740,9 +740,13 @@ mesh_state_cleanup(struct mesh_state* mstate) mesh = mstate->s.env->mesh; /* drop unsent replies */ if(!mstate->replies_sent) { - struct mesh_reply* rep; + struct mesh_reply* rep = mstate->reply_list; struct mesh_cb* cb; - for(rep=mstate->reply_list; rep; rep=rep->next) { + /* in tcp_req_info, the mstates linked are removed, but + * the reply_list is now NULL, so the remove-from-empty-list + * takes no time and also it does not do the mesh accounting */ + mstate->reply_list = NULL; + for(; rep; rep=rep->next) { comm_point_drop_reply(&rep->query_reply); mesh->num_reply_addrs--; } diff --git a/testcode/streamtcp.1 b/testcode/streamtcp.1 index 526c8e16..f02b168d 100644 --- a/testcode/streamtcp.1 +++ b/testcode/streamtcp.1 @@ -44,6 +44,11 @@ Use UDP instead of TCP. No retries are attempted. .B \-n Do not wait for the answer. .TP +.B \-a +Print answers on arrival. This mean queries are sent in sequence without +waiting for answer but if answers arrive in this time they are printed out. +After sending queries the program waits and prints the remainder. +.TP .B \-s Use SSL. .TP diff --git a/testcode/streamtcp.c b/testcode/streamtcp.c index 497e3d28..668d6360 100644 --- a/testcode/streamtcp.c +++ b/testcode/streamtcp.c @@ -73,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("-a print answers as they arrive.\n"); printf("-d secs delay after connection before sending query\n"); printf("-s use ssl\n"); printf("-h this help text\n"); @@ -203,13 +204,22 @@ recv_one(int fd, int udp, SSL* ssl, sldns_buffer* buf) uint16_t len; if(!udp) { if(ssl) { - if(SSL_read(ssl, (void*)&len, (int)sizeof(len)) <= 0) { + int sr = SSL_read(ssl, (void*)&len, (int)sizeof(len)); + if(sr == 0) { + printf("ssl: stream closed\n"); + exit(1); + } + if(sr < 0) { log_crypto_err("could not SSL_read"); exit(1); } } else { - if(recv(fd, (void*)&len, sizeof(len), 0) < - (ssize_t)sizeof(len)) { + ssize_t r = recv(fd, (void*)&len, sizeof(len), 0); + if(r == 0) { + printf("recv: stream closed\n"); + exit(1); + } + if(r < (ssize_t)sizeof(len)) { #ifndef USE_WINSOCK perror("read() len failed"); #else @@ -267,6 +277,37 @@ recv_one(int fd, int udp, SSL* ssl, sldns_buffer* buf) free(pktstr); } +/** see if we can receive any results */ +static void +print_any_answers(int fd, int udp, SSL* ssl, sldns_buffer* buf, + int* num_answers, int wait_all) +{ + /* see if the fd can read, if so, print one answer, repeat */ + int ret; + struct timeval tv, *waittv; + fd_set rfd; + while(*num_answers > 0) { + memset(&rfd, 0, sizeof(rfd)); + memset(&tv, 0, sizeof(tv)); + FD_ZERO(&rfd); + FD_SET(fd, &rfd); + if(wait_all) waittv = NULL; + else waittv = &tv; + ret = select(fd+1, &rfd, NULL, NULL, waittv); + if(ret < 0) { + if(errno == EINTR || errno == EAGAIN) continue; + perror("select() failed"); + exit(1); + } + if(ret == 0) { + if(wait_all) continue; + return; + } + (*num_answers) -= 1; + recv_one(fd, udp, ssl, buf); + } +} + static int get_random(void) { int r; @@ -278,12 +319,12 @@ 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 delay, - int num, char** qs) +send_em(const char* svr, int udp, int usessl, int noanswer, int onarrival, + int delay, int num, char** qs) { sldns_buffer* buf = sldns_buffer_new(65553); int fd = open_svr(svr, udp); - int i; + int i, wait_results = 0; SSL_CTX* ctx = NULL; SSL* ssl = NULL; if(!buf) fatal_exit("out of memory"); @@ -325,9 +366,15 @@ send_em(const char* svr, int udp, int usessl, int noanswer, int delay, write_q(fd, udp, ssl, buf, (uint16_t)get_random(), qs[i], qs[i+1], qs[i+2]); /* print at least one result */ - if(!noanswer) + if(onarrival) { + wait_results += 1; /* one more answer to fetch */ + print_any_answers(fd, udp, ssl, buf, &wait_results, 0); + } else if(!noanswer) { recv_one(fd, udp, ssl, buf); + } } + if(onarrival) + print_any_answers(fd, udp, ssl, buf, &wait_results, 1); if(usessl) { SSL_shutdown(ssl); @@ -368,6 +415,7 @@ int main(int argc, char** argv) const char* svr = "127.0.0.1"; int udp = 0; int noanswer = 0; + int onarrival = 0; int usessl = 0; int delay = 0; @@ -394,11 +442,14 @@ int main(int argc, char** argv) if(argc == 1) { usage(argv); } - while( (c=getopt(argc, argv, "f:hnsud:")) != -1) { + while( (c=getopt(argc, argv, "af:hnsud:")) != -1) { switch(c) { case 'f': svr = optarg; break; + case 'a': + onarrival = 1; + break; case 'n': noanswer = 1; break; @@ -446,7 +497,7 @@ int main(int argc, char** argv) (void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); #endif } - send_em(svr, udp, usessl, noanswer, delay, argc, argv); + send_em(svr, udp, usessl, noanswer, onarrival, delay, argc, argv); checklock_stop(); #ifdef USE_WINSOCK WSACleanup(); diff --git a/testdata/tcp_req_order.tdir/tcp_req_order.conf b/testdata/tcp_req_order.tdir/tcp_req_order.conf new file mode 100644 index 00000000..40d6f55c --- /dev/null +++ b/testdata/tcp_req_order.tdir/tcp_req_order.conf @@ -0,0 +1,22 @@ +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 + + local-zone: "example.net" static + local-data: "www1.example.net. IN A 1.2.3.1" + local-data: "www2.example.net. IN A 1.2.3.2" + local-data: "www3.example.net. IN A 1.2.3.3" + tcp-upstream: yes + local-zone: "drop.net" deny + +forward-zone: + name: "." + forward-addr: "127.0.0.1@@TOPORT@" diff --git a/testdata/tcp_req_order.tdir/tcp_req_order.dsc b/testdata/tcp_req_order.tdir/tcp_req_order.dsc new file mode 100644 index 00000000..f24e9007 --- /dev/null +++ b/testdata/tcp_req_order.tdir/tcp_req_order.dsc @@ -0,0 +1,16 @@ +BaseName: tcp_req_order +Version: 1.0 +Description: Test tcp request order processing. +CreationDate: Mon Jan 14 13:34:00 CET 2018 +Maintainer: Wouter Wijngaards +Category: +Component: +CmdDepends: +Depends: +Help: +Pre: tcp_req_order.pre +Post: tcp_req_order.post +Test: tcp_req_order.test +AuxFiles: +Passed: +Failure: diff --git a/testdata/tcp_req_order.tdir/tcp_req_order.post b/testdata/tcp_req_order.tdir/tcp_req_order.post new file mode 100644 index 00000000..43372764 --- /dev/null +++ b/testdata/tcp_req_order.tdir/tcp_req_order.post @@ -0,0 +1,11 @@ +# #-- tcp_req_order.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 +cat unbound.log diff --git a/testdata/tcp_req_order.tdir/tcp_req_order.pre b/testdata/tcp_req_order.tdir/tcp_req_order.pre new file mode 100644 index 00000000..b2191f06 --- /dev/null +++ b/testdata/tcp_req_order.tdir/tcp_req_order.pre @@ -0,0 +1,31 @@ +# #-- tcp_req_order.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_req_order.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_req_order.conf > ub.conf +# start unbound in the background +PRE="../.." +$PRE/unbound -vvvv -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_req_order.tdir/tcp_req_order.test b/testdata/tcp_req_order.tdir/tcp_req_order.test new file mode 100644 index 00000000..ecbde306 --- /dev/null +++ b/testdata/tcp_req_order.tdir/tcp_req_order.test @@ -0,0 +1,341 @@ +# #-- tcp_req_order.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 + +PRE="../.." +. ../common.sh +get_make +(cd $PRE; $MAKE streamtcp) + +# this test query should just work (server is up) +echo "> query www1.example.net." +$PRE/streamtcp -f 127.0.0.1@$UNBOUND_PORT www1.example.net. A IN >outfile 2>&1 +cat outfile +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 +fi +if grep "www1.example.net" outfile | grep "1.2.3.1"; then + echo "content OK" +else + echo "result contents not OK" + echo "> cat logfiles" + cat outfile + cat fwd.log + cat unbound.log + echo "result contents not OK" + exit 1 +fi +echo "OK" + +# multiple requests (from localdata) +echo "> query www1.example.net. www2.example.net. www3.example.net." +$PRE/streamtcp -f 127.0.0.1@$UNBOUND_PORT www1.example.net. A IN www2.example.net A IN www3.example.net A IN >outfile 2>&1 +cat outfile +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 +fi +if grep "www1.example.net" outfile | grep "1.2.3.1"; then + echo "content OK" +else + echo "result contents not OK" + echo "> cat logfiles" + cat outfile + cat fwd.log + cat unbound.log + echo "result contents not OK" + exit 1 +fi +if grep "www2.example.net" outfile | grep "1.2.3.2"; then + echo "content OK" +else + echo "result contents not OK" + echo "> cat logfiles" + cat outfile + cat fwd.log + cat unbound.log + echo "result contents not OK" + exit 1 +fi +if grep "www3.example.net" outfile | grep "1.2.3.3"; then + echo "content OK" +else + echo "result contents not OK" + echo "> cat logfiles" + cat outfile + cat fwd.log + cat unbound.log + echo "result contents not OK" + exit 1 +fi + +# out of order requests, the example.com elements take 2 seconds to wait. +echo "" +echo "> query www1.example.net. www.example.com. www2.example.net. www2.example.com. www3.example.net." +$PRE/streamtcp -a -f 127.0.0.1@$UNBOUND_PORT www1.example.net. A IN www.example.com. A IN www2.example.net A IN www2.example.com. A IN www3.example.net A IN >outfile 2>&1 +cat outfile +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 +fi +if grep "www1.example.net" outfile | grep "1.2.3.1"; then + echo "content OK" +else + echo "result contents not OK" + echo "> cat logfiles" + cat outfile + cat fwd.log + cat unbound.log + echo "result contents not OK" + exit 1 +fi +if grep "www2.example.net" outfile | grep "1.2.3.2"; then + echo "content OK" +else + echo "result contents not OK" + echo "> cat logfiles" + cat outfile + cat fwd.log + cat unbound.log + echo "result contents not OK" + exit 1 +fi +if grep "www3.example.net" outfile | grep "1.2.3.3"; then + echo "content OK" +else + echo "result contents not OK" + echo "> cat logfiles" + cat outfile + cat fwd.log + cat unbound.log + echo "result contents not OK" + exit 1 +fi +if grep "www.example.com" outfile | grep "10.20.30.40"; then + echo "content OK" +else + echo "result contents not OK" + echo "> cat logfiles" + cat outfile + cat fwd.log + cat unbound.log + echo "result contents not OK" + exit 1 +fi +if grep "www2.example.com" outfile | grep "10.20.30.42"; then + echo "content OK" +else + echo "result contents not OK" + echo "> cat logfiles" + cat outfile + cat fwd.log + cat unbound.log + echo "result contents not OK" + exit 1 +fi + +# out of order requests, the example.com elements take 2 seconds to wait. +# www.example.com present twice, answered twice. +echo "" +echo "> query www1.example.net. www.example.com. www2.example.net. www.example.com. www3.example.net." +$PRE/streamtcp -a -f 127.0.0.1@$UNBOUND_PORT www1.example.net. A IN www.example.com. A IN www2.example.net A IN www.example.com. A IN www3.example.net A IN >outfile 2>&1 +cat outfile +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 +fi +if grep "www1.example.net" outfile | grep "1.2.3.1"; then + echo "content OK" +else + echo "result contents not OK" + echo "> cat logfiles" + cat outfile + cat fwd.log + cat unbound.log + echo "result contents not OK" + exit 1 +fi +if grep "www2.example.net" outfile | grep "1.2.3.2"; then + echo "content OK" +else + echo "result contents not OK" + echo "> cat logfiles" + cat outfile + cat fwd.log + cat unbound.log + echo "result contents not OK" + exit 1 +fi +if grep "www3.example.net" outfile | grep "1.2.3.3"; then + echo "content OK" +else + echo "result contents not OK" + echo "> cat logfiles" + cat outfile + cat fwd.log + cat unbound.log + echo "result contents not OK" + exit 1 +fi +if grep "www.example.com" outfile | grep "10.20.30.40"; then + echo "content OK" +else + echo "result contents not OK" + echo "> cat logfiles" + cat outfile + cat fwd.log + cat unbound.log + echo "result contents not OK" + exit 1 +fi + +# out of order requests, the example.com elements take 2 seconds to wait. +# www3.example.com present twice, answered twice. +echo "" +echo "> query www1.example.net. www3.example.com. www2.example.net. www3.example.com. www3.example.net." +$PRE/streamtcp -a -f 127.0.0.1@$UNBOUND_PORT www1.example.net. A IN www3.example.com. A IN www2.example.net A IN www3.example.com. A IN www3.example.net A IN >outfile 2>&1 +cat outfile +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 +fi +if grep "www1.example.net" outfile | grep "1.2.3.1"; then + echo "content OK" +else + echo "result contents not OK" + echo "> cat logfiles" + cat outfile + cat fwd.log + cat unbound.log + echo "result contents not OK" + exit 1 +fi +if grep "www2.example.net" outfile | grep "1.2.3.2"; then + echo "content OK" +else + echo "result contents not OK" + echo "> cat logfiles" + cat outfile + cat fwd.log + cat unbound.log + echo "result contents not OK" + exit 1 +fi +if grep "www3.example.net" outfile | grep "1.2.3.3"; then + echo "content OK" +else + echo "result contents not OK" + echo "> cat logfiles" + cat outfile + cat fwd.log + cat unbound.log + echo "result contents not OK" + exit 1 +fi +if grep "www3.example.com" outfile | grep "10.20.30.43"; then + echo "content OK" +else + echo "result contents not OK" + echo "> cat logfiles" + cat outfile + cat fwd.log + cat unbound.log + echo "result contents not OK" + exit 1 +fi + +echo "" +echo "> query www4.example.com. www3.example.net." +$PRE/streamtcp -a -f 127.0.0.1@$UNBOUND_PORT www4.example.com. A IN www3.example.net A IN >outfile 2>&1 +cat outfile +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 +fi +if grep "www3.example.net" outfile | grep "1.2.3.3"; then + echo "content OK" +else + echo "result contents not OK" + echo "> cat logfiles" + cat outfile + cat fwd.log + cat unbound.log + echo "result contents not OK" + exit 1 +fi +if grep "www4.example.com" outfile | grep "10.20.30.44"; then + echo "content OK" +else + echo "result contents not OK" + echo "> cat logfiles" + cat outfile + cat fwd.log + cat unbound.log + echo "result contents not OK" + exit 1 +fi + +echo "" +echo "> query a1.example.com. - a100.example.com." +$PRE/streamtcp -a -f 127.0.0.1@$UNBOUND_PORT www6.example.com. A IN a1.a.example.com. A IN a2.a.example.com. A IN a3.a.example.com. A IN a4.a.example.com. A IN a5.a.example.com. A IN a6.a.example.com. A IN a7.a.example.com. A IN a8.a.example.com. A IN a9.a.example.com. A IN a10.a.example.com. A IN a11.a.example.com. A IN a12.a.example.com. A IN a13.a.example.com. A IN a14.a.example.com. A IN a15.a.example.com. A IN a16.a.example.com. A IN a17.a.example.com. A IN a18.a.example.com. A IN a19.a.example.com. A IN a20.a.example.com. A IN a21.a.example.com. A IN a22.a.example.com. A IN a23.a.example.com. A IN a24.a.example.com. A IN a25.a.example.com. A IN a26.a.example.com. A IN a27.a.example.com. A IN a28.a.example.com. A IN a29.a.example.com. A IN a30.a.example.com. A IN a31.a.example.com. A IN a32.a.example.com. A IN a33.a.example.com. A IN a34.a.example.com. A IN a35.a.example.com. A IN a36.a.example.com. A IN a37.a.example.com. A IN a38.a.example.com. A IN a39.a.example.com. A IN a40.a.example.com. A IN a41.a.example.com. A IN a42.a.example.com. A IN a43.a.example.com. A IN a44.a.example.com. A IN a45.a.example.com. A IN a46.a.example.com. A IN a47.a.example.com. A IN a48.a.example.com. A IN a49.a.example.com. A IN a50.a.example.com. A IN a51.a.example.com. A IN a52.a.example.com. A IN a53.a.example.com. A IN a54.a.example.com. A IN a55.a.example.com. A IN a56.a.example.com. A IN a57.a.example.com. A IN a58.a.example.com. A IN a59.a.example.com. A IN a60.a.example.com. A IN a61.a.example.com. A IN a62.a.example.com. A IN a63.a.example.com. A IN a64.a.example.com. A IN a65.a.example.com. A IN a66.a.example.com. A IN a67.a.example.com. A IN a68.a.example.com. A IN a69.a.example.com. A IN a70.a.example.com. A IN a71.a.example.com. A IN a72.a.example.com. A IN a73.a.example.com. A IN a74.a.example.com. A IN a75.a.example.com. A IN a76.a.example.com. A IN a77.a.example.com. A IN a78.a.example.com. A IN a79.a.example.com. A IN a80.a.example.com. A IN a81.a.example.com. A IN a82.a.example.com. A IN a83.a.example.com. A IN a84.a.example.com. A IN a85.a.example.com. A IN a86.a.example.com. A IN a87.a.example.com. A IN a88.a.example.com. A IN a89.a.example.com. A IN a90.a.example.com. A IN a91.a.example.com. A IN a92.a.example.com. A IN a93.a.example.com. A IN a94.a.example.com. A IN a95.a.example.com. A IN a96.a.example.com. A IN a97.a.example.com. A IN a98.a.example.com. A IN a99.a.example.com. A IN a100.a.example.com. A IN >outfile 2>&1 +cat outfile +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 +fi +grep "a.example.com. IN A" outfile + +echo "" +echo "> query www5.example.net. www3.example.net. www.drop.net." +$PRE/streamtcp -a -f 127.0.0.1@$UNBOUND_PORT www5.example.com. A IN www3.example.net A IN www.drop.net A IN >outfile 2>&1 +cat outfile +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 +fi + +echo "OK" +exit 0 diff --git a/testdata/tcp_req_order.tdir/tcp_req_order.testns b/testdata/tcp_req_order.tdir/tcp_req_order.testns new file mode 100644 index 00000000..c53941b6 --- /dev/null +++ b/testdata/tcp_req_order.tdir/tcp_req_order.testns @@ -0,0 +1,74 @@ +; nameserver test file +$ORIGIN example.com. +$TTL 3600 + +ENTRY_BEGIN +MATCH 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 + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA NOERROR +ADJUST copy_id sleep=2 +SECTION QUESTION +www4 IN A +SECTION ANSWER +www4 IN A 10.20.30.44 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA NOERROR +ADJUST copy_id sleep=2 +SECTION QUESTION +www5 IN A +SECTION ANSWER +www5 IN A 10.20.30.45 +ENTRY_END + +ENTRY_BEGIN +MATCH opcode qtype qname +REPLY QR AA NOERROR +ADJUST copy_id sleep=2 +SECTION QUESTION +www6 IN A +SECTION ANSWER +www6 IN A 10.20.30.46 +ENTRY_END + +; lots of noerror/nodata answers for other queries (a.. queries) +ENTRY_BEGIN +MATCH opcode qtype subdomain +REPLY QR AA NOERROR +ADJUST copy_id copy_query +SECTION QUESTION +a.example.com. IN A +SECTION AUTHORITY +example.com. IN SOA ns hostmaster 2019 28800 7200 604800 3600 +ENTRY_END