- 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
This commit is contained in:
Wouter Wijngaards 2019-01-14 15:52:50 +00:00
parent dd19026e91
commit ae9fe1a10e
11 changed files with 578 additions and 14 deletions

View file

@ -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 11 January 2018: Wouter
- Initial commit for out-of-order processing for TCP and TLS. - Initial commit for out-of-order processing for TCP and TLS.

View file

@ -72,6 +72,9 @@
/** number of queued TCP connections for listen() */ /** number of queued TCP connections for listen() */
#define TCP_BACKLOG 256 #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. * Debug print of the getaddrinfo returned address.
* @param addr: the address returned. * @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 */ /** setup listening for read or write */
static void static void
tcp_req_info_setup_listen(struct tcp_req_info* req) 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) tcp_req_info_handle_read_close(struct tcp_req_info* req)
{ {
verbose(VERB_ALGO, "tcp channel read side closed %d", req->cp->fd); 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) { if(req->num_done_req != 0) {
tcp_req_pickup_next_result(req); tcp_req_pickup_next_result(req);
tcp_req_info_setup_listen(req); tcp_req_info_setup_listen(req);
return 1; return 1;
} }
/* if nothing to do, this closes the connection */
if(req->num_open_req == 0 && req->num_done_req == 0) if(req->num_open_req == 0 && req->num_done_req == 0)
return 0; return 0;
/* otherwise, we must be waiting for dns resolve, wait with timeout */
req->read_is_closed = 1; req->read_is_closed = 1;
tcp_req_info_setup_listen(req); tcp_req_info_setup_listen(req);
return 1; return 1;

View file

@ -740,9 +740,13 @@ mesh_state_cleanup(struct mesh_state* mstate)
mesh = mstate->s.env->mesh; mesh = mstate->s.env->mesh;
/* drop unsent replies */ /* drop unsent replies */
if(!mstate->replies_sent) { if(!mstate->replies_sent) {
struct mesh_reply* rep; struct mesh_reply* rep = mstate->reply_list;
struct mesh_cb* cb; 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); comm_point_drop_reply(&rep->query_reply);
mesh->num_reply_addrs--; mesh->num_reply_addrs--;
} }

View file

@ -44,6 +44,11 @@ Use UDP instead of TCP. No retries are attempted.
.B \-n .B \-n
Do not wait for the answer. Do not wait for the answer.
.TP .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 .B \-s
Use SSL. Use SSL.
.TP .TP

View file

@ -73,6 +73,7 @@ static void usage(char* argv[])
printf("-f server what ipaddr@portnr to send the queries to\n"); printf("-f server what ipaddr@portnr to send the queries to\n");
printf("-u use UDP. No retries are attempted.\n"); printf("-u use UDP. No retries are attempted.\n");
printf("-n do not wait for an answer.\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("-d secs delay after connection before sending query\n");
printf("-s use ssl\n"); printf("-s use ssl\n");
printf("-h this help text\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; uint16_t len;
if(!udp) { if(!udp) {
if(ssl) { 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"); log_crypto_err("could not SSL_read");
exit(1); exit(1);
} }
} else { } else {
if(recv(fd, (void*)&len, sizeof(len), 0) < ssize_t r = recv(fd, (void*)&len, sizeof(len), 0);
(ssize_t)sizeof(len)) { if(r == 0) {
printf("recv: stream closed\n");
exit(1);
}
if(r < (ssize_t)sizeof(len)) {
#ifndef USE_WINSOCK #ifndef USE_WINSOCK
perror("read() len failed"); perror("read() len failed");
#else #else
@ -267,6 +277,37 @@ recv_one(int fd, int udp, SSL* ssl, sldns_buffer* buf)
free(pktstr); 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) static int get_random(void)
{ {
int r; int r;
@ -278,12 +319,12 @@ static int get_random(void)
/** send the TCP queries and print answers */ /** send the TCP queries and print answers */
static void static void
send_em(const char* svr, int udp, int usessl, int noanswer, int delay, send_em(const char* svr, int udp, int usessl, int noanswer, int onarrival,
int num, char** qs) int delay, int num, char** qs)
{ {
sldns_buffer* buf = sldns_buffer_new(65553); sldns_buffer* buf = sldns_buffer_new(65553);
int fd = open_svr(svr, udp); int fd = open_svr(svr, udp);
int i; int i, wait_results = 0;
SSL_CTX* ctx = NULL; SSL_CTX* ctx = NULL;
SSL* ssl = NULL; SSL* ssl = NULL;
if(!buf) fatal_exit("out of memory"); 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], write_q(fd, udp, ssl, buf, (uint16_t)get_random(), qs[i],
qs[i+1], qs[i+2]); qs[i+1], qs[i+2]);
/* print at least one result */ /* 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); recv_one(fd, udp, ssl, buf);
}
} }
if(onarrival)
print_any_answers(fd, udp, ssl, buf, &wait_results, 1);
if(usessl) { if(usessl) {
SSL_shutdown(ssl); SSL_shutdown(ssl);
@ -368,6 +415,7 @@ int main(int argc, char** argv)
const char* svr = "127.0.0.1"; const char* svr = "127.0.0.1";
int udp = 0; int udp = 0;
int noanswer = 0; int noanswer = 0;
int onarrival = 0;
int usessl = 0; int usessl = 0;
int delay = 0; int delay = 0;
@ -394,11 +442,14 @@ int main(int argc, char** argv)
if(argc == 1) { if(argc == 1) {
usage(argv); usage(argv);
} }
while( (c=getopt(argc, argv, "f:hnsud:")) != -1) { while( (c=getopt(argc, argv, "af:hnsud:")) != -1) {
switch(c) { switch(c) {
case 'f': case 'f':
svr = optarg; svr = optarg;
break; break;
case 'a':
onarrival = 1;
break;
case 'n': case 'n':
noanswer = 1; noanswer = 1;
break; break;
@ -446,7 +497,7 @@ int main(int argc, char** argv)
(void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL); (void)OPENSSL_init_ssl(OPENSSL_INIT_LOAD_SSL_STRINGS, NULL);
#endif #endif
} }
send_em(svr, udp, usessl, noanswer, delay, argc, argv); send_em(svr, udp, usessl, noanswer, onarrival, delay, argc, argv);
checklock_stop(); checklock_stop();
#ifdef USE_WINSOCK #ifdef USE_WINSOCK
WSACleanup(); WSACleanup();

View file

@ -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@"

View file

@ -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:

View file

@ -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

View file

@ -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

View file

@ -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

View file

@ -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