1#!/bin/sh
2
3# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
4#
5# SPDX-License-Identifier: MPL-2.0
6#
7# This Source Code Form is subject to the terms of the Mozilla Public
8# License, v. 2.0.  If a copy of the MPL was not distributed with this
9# file, you can obtain one at https://mozilla.org/MPL/2.0/.
10#
11# See the COPYRIGHT file distributed with this work for additional
12# information regarding copyright ownership.
13
14set -e
15
16. ../conf.sh
17
18DIGOPTS="+short -p ${PORT}"
19RNDCCMD="$RNDC -p ${CONTROLPORT} -c ../_common/rndc.conf"
20
21status=0
22
23# dnstap_data_ready <fstrm_capture_PID> <capture_file> <min_file_size>
24# Flushes capture_file and checks wheter its size is >= min_file_size.
25dnstap_data_ready() {
26  # Process id of running fstrm_capture.
27  fstrm_capture_pid=$1
28  # Output file provided to fstrm_capture via -w switch.
29  capture_file=$2
30  # Minimum expected file size.
31  min_size_expected=$3
32
33  kill -HUP $fstrm_capture_pid
34  file_size=$(wc -c <"$capture_file" | tr -d ' ')
35  if [ $file_size -lt $min_size_expected ]; then
36    return 1
37  fi
38}
39
40for bad in bad-*.conf; do
41  ret=0
42  echo_i "checking that named-checkconf detects error in $bad"
43  {
44    $CHECKCONF $bad >/dev/null 2>&1
45    rc=$?
46  } || true
47  if [ $rc != 1 ]; then
48    echo_i "failed"
49    ret=1
50  fi
51  status=$((status + ret))
52done
53
54for good in good-*.conf; do
55  ret=0
56  echo_i "checking that named-checkconf detects no error in $good"
57  {
58    $CHECKCONF $good >/dev/null 2>&1
59    rc=$?
60  } || true
61  if [ $rc != 0 ]; then
62    echo_i "failed"
63    ret=1
64  fi
65  status=$((status + ret))
66done
67
68echo_i "wait for servers to finish loading"
69ret=0
70wait_for_log 20 "all zones loaded" ns1/named.run || ret=1
71wait_for_log 20 "all zones loaded" ns2/named.run || ret=1
72wait_for_log 20 "all zones loaded" ns3/named.run || ret=1
73wait_for_log 20 "all zones loaded" ns4/named.run || ret=1
74if [ $ret != 0 ]; then echo_i "failed"; fi
75status=$((status + ret))
76
77# both the 'a.example/A' lookup and the './NS' lookup to ns1
78# need to complete before reopening/rolling for the counts to
79# be correct.
80
81echo_i "prime cache"
82ret=0
83$DIG $DIGOPTS @10.53.0.3 a.example >dig.out || true
84wait_for_log 20 "(.): reset client" ns1/named.run || true
85if [ $ret != 0 ]; then echo_i "failed"; fi
86status=$((status + ret))
87
88# check three different dnstap reopen/roll methods:
89# ns1: dnstap-reopen; ns2: dnstap -reopen; ns3: dnstap -roll
90mv ns1/dnstap.out ns1/dnstap.out.save
91mv ns2/dnstap.out ns2/dnstap.out.save
92
93if [ -n "$FSTRM_CAPTURE" ]; then
94  ret=0
95  echo_i "starting fstrm_capture"
96  $FSTRM_CAPTURE -t protobuf:dnstap.Dnstap -u ns4/dnstap.out \
97    -w dnstap.out >fstrm_capture.out.1 2>&1 &
98  fstrm_capture_pid=$!
99  wait_for_log 10 "socket path ns4/dnstap.out" fstrm_capture.out.1 || ret=1
100  if [ $ret != 0 ]; then echo_i "failed"; fi
101  status=$((status + ret))
102fi
103
104echo_i "reopen/roll capture streams"
105ret=0
106$RNDCCMD -s 10.53.0.1 dnstap-reopen | sed 's/^/ns1 /' | cat_i
107$RNDCCMD -s 10.53.0.2 dnstap -reopen | sed 's/^/ns2 /' | cat_i
108$RNDCCMD -s 10.53.0.3 dnstap -roll | sed 's/^/ns3 /' | cat_i
109$RNDCCMD -s 10.53.0.4 dnstap -reopen | sed 's/^/ns4 /' | cat_i
110
111echo_i "send test traffic"
112ret=0
113$DIG $DIGOPTS @10.53.0.3 a.example >dig.out || ret=1
114
115# send an UPDATE to ns2
116$NSUPDATE <<-EOF
117server 10.53.0.2 ${PORT}
118zone example
119update add b.example 3600 in a 10.10.10.10
120send
121EOF
122
123# XXX: file output should be flushed once a second according
124# to the libfstrm source, but it doesn't seem to happen until
125# enough data has accumulated. to get all the output, we stop
126# the name servers, forcing a flush on shutdown. it would be
127# nice to find a better way to do this.
128$RNDCCMD -s 10.53.0.1 stop | sed 's/^/ns1 /' | cat_i
129$RNDCCMD -s 10.53.0.2 stop | sed 's/^/ns2 /' | cat_i
130$RNDCCMD -s 10.53.0.3 stop | sed 's/^/ns3 /' | cat_i
131
132sleep 1
133
134echo_i "checking initial message counts"
135
136udp1=$($DNSTAPREAD ns1/dnstap.out.save | grep "UDP " | wc -l)
137tcp1=$($DNSTAPREAD ns1/dnstap.out.save | grep "TCP " | wc -l)
138aq1=$($DNSTAPREAD ns1/dnstap.out.save | grep "AQ " | wc -l)
139ar1=$($DNSTAPREAD ns1/dnstap.out.save | grep "AR " | wc -l)
140cq1=$($DNSTAPREAD ns1/dnstap.out.save | grep "CQ " | wc -l)
141cr1=$($DNSTAPREAD ns1/dnstap.out.save | grep "CR " | wc -l)
142rq1=$($DNSTAPREAD ns1/dnstap.out.save | grep "RQ " | wc -l)
143rr1=$($DNSTAPREAD ns1/dnstap.out.save | grep "RR " | wc -l)
144uq1=$($DNSTAPREAD ns1/dnstap.out.save | grep "UQ " | wc -l)
145ur1=$($DNSTAPREAD ns1/dnstap.out.save | grep "UR " | wc -l)
146
147udp2=$($DNSTAPREAD ns2/dnstap.out.save | grep "UDP " | wc -l)
148tcp2=$($DNSTAPREAD ns2/dnstap.out.save | grep "TCP " | wc -l)
149aq2=$($DNSTAPREAD ns2/dnstap.out.save | grep "AQ " | wc -l)
150ar2=$($DNSTAPREAD ns2/dnstap.out.save | grep "AR " | wc -l)
151cq2=$($DNSTAPREAD ns2/dnstap.out.save | grep "CQ " | wc -l)
152cr2=$($DNSTAPREAD ns2/dnstap.out.save | grep "CR " | wc -l)
153rq2=$($DNSTAPREAD ns2/dnstap.out.save | grep "RQ " | wc -l)
154rr2=$($DNSTAPREAD ns2/dnstap.out.save | grep "RR " | wc -l)
155uq2=$($DNSTAPREAD ns2/dnstap.out.save | grep "UQ " | wc -l)
156ur2=$($DNSTAPREAD ns2/dnstap.out.save | grep "UR " | wc -l)
157
158mv ns3/dnstap.out.0 ns3/dnstap.out.save
159udp3=$($DNSTAPREAD ns3/dnstap.out.save | grep "UDP " | wc -l)
160tcp3=$($DNSTAPREAD ns3/dnstap.out.save | grep "TCP " | wc -l)
161aq3=$($DNSTAPREAD ns3/dnstap.out.save | grep "AQ " | wc -l)
162ar3=$($DNSTAPREAD ns3/dnstap.out.save | grep "AR " | wc -l)
163cq3=$($DNSTAPREAD ns3/dnstap.out.save | grep "CQ " | wc -l)
164cr3=$($DNSTAPREAD ns3/dnstap.out.save | grep "CR " | wc -l)
165rq3=$($DNSTAPREAD ns3/dnstap.out.save | grep "RQ " | wc -l)
166rr3=$($DNSTAPREAD ns3/dnstap.out.save | grep "RR " | wc -l)
167uq3=$($DNSTAPREAD ns3/dnstap.out.save | grep "UQ " | wc -l)
168ur3=$($DNSTAPREAD ns3/dnstap.out.save | grep "UR " | wc -l)
169
170echo_i "checking UDP message counts"
171ret=0
172[ $udp1 -eq 0 ] || {
173  echo_i "ns1 $udp1 expected 0"
174  ret=1
175}
176[ $udp2 -eq 2 ] || {
177  echo_i "ns2 $udp2 expected 2"
178  ret=1
179}
180[ $udp3 -eq 4 ] || {
181  echo_i "ns3 $udp3 expected 4"
182  ret=1
183}
184if [ $ret != 0 ]; then echo_i "failed"; fi
185status=$((status + ret))
186
187echo_i "checking TCP message counts"
188ret=0
189[ $tcp1 -eq 6 ] || {
190  echo_i "ns1 $tcp1 expected 6"
191  ret=1
192}
193[ $tcp2 -eq 2 ] || {
194  echo_i "ns2 $tcp2 expected 2"
195  ret=1
196}
197[ $tcp3 -eq 6 ] || {
198  echo_i "ns3 $tcp3 expected 6"
199  ret=1
200}
201if [ $ret != 0 ]; then echo_i "failed"; fi
202status=$((status + ret))
203
204echo_i "checking AUTH_QUERY message counts"
205ret=0
206[ $aq1 -eq 3 ] || {
207  echo_i "ns1 $aq1 exepcted 3"
208  ret=1
209}
210[ $aq2 -eq 2 ] || {
211  echo_i "ns2 $aq2 expected 2"
212  ret=1
213}
214[ $aq3 -eq 1 ] || {
215  echo_i "ns3 $aq3 expected 1"
216  ret=1
217}
218if [ $ret != 0 ]; then echo_i "failed"; fi
219status=$((status + ret))
220
221echo_i "checking AUTH_RESPONSE message counts"
222ret=0
223[ $ar1 -eq 2 ] || {
224  echo_i "ns1 $ar1 expected 2"
225  ret=1
226}
227[ $ar2 -eq 1 ] || {
228  echo_i "ns2 $ar2 expected 1"
229  ret=1
230}
231[ $ar3 -eq 0 ] || {
232  echo_i "ns3 $ar3 expected 0"
233  ret=1
234}
235if [ $ret != 0 ]; then echo_i "failed"; fi
236status=$((status + ret))
237
238echo_i "checking CLIENT_QUERY message counts"
239ret=0
240[ $cq1 -eq 0 ] || {
241  echo_i "ns1 $cq1 expected 0"
242  ret=1
243}
244[ $cq2 -eq 0 ] || {
245  echo_i "ns2 $cq2 expected 0"
246  ret=1
247}
248[ $cq3 -eq 1 ] || {
249  echo_i "ns3 $cq3 expected 1"
250  ret=1
251}
252if [ $ret != 0 ]; then echo_i "failed"; fi
253status=$((status + ret))
254
255echo_i "checking CLIENT_RESPONSE message counts"
256ret=0
257[ $cr1 -eq 1 ] || {
258  echo_i "ns1 $cr1 expected 1"
259  ret=1
260}
261[ $cr2 -eq 1 ] || {
262  echo_i "ns2 $cr2 expected 1"
263  ret=1
264}
265[ $cr3 -eq 2 ] || {
266  echo_i "ns3 $cr3 expected 2"
267  ret=1
268}
269if [ $ret != 0 ]; then echo_i "failed"; fi
270status=$((status + ret))
271
272echo_i "checking RESOLVER_QUERY message counts"
273ret=0
274[ $rq1 -eq 0 ] || {
275  echo_i "ns1 $rq1 expected 0"
276  ret=1
277}
278[ $rq2 -eq 0 ] || {
279  echo_i "ns2 $rq2 expected 0"
280  ret=1
281}
282[ $rq3 -eq 3 ] || {
283  echo_i "ns3 $rq3 expected 3"
284  ret=1
285}
286if [ $ret != 0 ]; then echo_i "failed"; fi
287status=$((status + ret))
288
289echo_i "checking RESOLVER_RESPONSE message counts"
290ret=0
291[ $rr1 -eq 0 ] || {
292  echo_i "ns1 $rr1 expected 0"
293  ret=1
294}
295[ $rr2 -eq 0 ] || {
296  echo_i "ns2 $rr2 expected 0"
297  ret=1
298}
299[ $rr3 -eq 3 ] || {
300  echo_i "ns3 $rr3 expected 3"
301  ret=1
302}
303if [ $ret != 0 ]; then echo_i "failed"; fi
304status=$((status + ret))
305
306echo_i "checking UPDATE_QUERY message counts"
307ret=0
308[ $uq1 -eq 0 ] || {
309  echo_i "ns1 $uq1 expected 0"
310  ret=1
311}
312[ $uq2 -eq 0 ] || {
313  echo_i "ns2 $uq2 expected 0"
314  ret=1
315}
316[ $uq3 -eq 0 ] || {
317  echo_i "ns3 $uq3 expected 0"
318  ret=1
319}
320if [ $ret != 0 ]; then echo_i "failed"; fi
321status=$((status + ret))
322
323echo_i "checking UPDATE_RESPONSE message counts"
324ret=0
325[ $ur1 -eq 0 ] || {
326  echo_i "ns1 $ur1 expected 0"
327  ret=1
328}
329[ $ur2 -eq 0 ] || {
330  echo_i "ns2 $ur2 expected 0"
331  ret=1
332}
333[ $ur3 -eq 0 ] || {
334  echo_i "ns3 $ur3 expected 0"
335  ret=1
336}
337if [ $ret != 0 ]; then echo_i "failed"; fi
338status=$((status + ret))
339
340echo_i "checking reopened message counts"
341
342udp1=$($DNSTAPREAD ns1/dnstap.out | grep "UDP " | wc -l)
343tcp1=$($DNSTAPREAD ns1/dnstap.out | grep "TCP " | wc -l)
344aq1=$($DNSTAPREAD ns1/dnstap.out | grep "AQ " | wc -l)
345ar1=$($DNSTAPREAD ns1/dnstap.out | grep "AR " | wc -l)
346cq1=$($DNSTAPREAD ns1/dnstap.out | grep "CQ " | wc -l)
347cr1=$($DNSTAPREAD ns1/dnstap.out | grep "CR " | wc -l)
348rq1=$($DNSTAPREAD ns1/dnstap.out | grep "RQ " | wc -l)
349rr1=$($DNSTAPREAD ns1/dnstap.out | grep "RR " | wc -l)
350uq1=$($DNSTAPREAD ns1/dnstap.out | grep "UQ " | wc -l)
351ur1=$($DNSTAPREAD ns1/dnstap.out | grep "UR " | wc -l)
352
353udp2=$($DNSTAPREAD ns2/dnstap.out | grep "UDP " | wc -l)
354tcp2=$($DNSTAPREAD ns2/dnstap.out | grep "TCP " | wc -l)
355aq2=$($DNSTAPREAD ns2/dnstap.out | grep "AQ " | wc -l)
356ar2=$($DNSTAPREAD ns2/dnstap.out | grep "AR " | wc -l)
357cq2=$($DNSTAPREAD ns2/dnstap.out | grep "CQ " | wc -l)
358cr2=$($DNSTAPREAD ns2/dnstap.out | grep "CR " | wc -l)
359rq2=$($DNSTAPREAD ns2/dnstap.out | grep "RQ " | wc -l)
360rr2=$($DNSTAPREAD ns2/dnstap.out | grep "RR " | wc -l)
361uq2=$($DNSTAPREAD ns2/dnstap.out | grep "UQ " | wc -l)
362ur2=$($DNSTAPREAD ns2/dnstap.out | grep "UR " | wc -l)
363
364udp3=$($DNSTAPREAD ns3/dnstap.out | grep "UDP " | wc -l)
365tcp3=$($DNSTAPREAD ns3/dnstap.out | grep "TCP " | wc -l)
366aq3=$($DNSTAPREAD ns3/dnstap.out | grep "AQ " | wc -l)
367ar3=$($DNSTAPREAD ns3/dnstap.out | grep "AR " | wc -l)
368cq3=$($DNSTAPREAD ns3/dnstap.out | grep "CQ " | wc -l)
369cr3=$($DNSTAPREAD ns3/dnstap.out | grep "CR " | wc -l)
370rq3=$($DNSTAPREAD ns3/dnstap.out | grep "RQ " | wc -l)
371rr3=$($DNSTAPREAD ns3/dnstap.out | grep "RR " | wc -l)
372uq3=$($DNSTAPREAD ns3/dnstap.out | grep "UQ " | wc -l)
373ur3=$($DNSTAPREAD ns3/dnstap.out | grep "UR " | wc -l)
374
375echo_i "checking UDP message counts"
376ret=0
377[ $udp1 -eq 0 ] || {
378  echo_i "ns1 $udp1 expected 0"
379  ret=1
380}
381[ $udp2 -eq 2 ] || {
382  echo_i "ns2 $udp2 expected 2"
383  ret=1
384}
385[ $udp3 -eq 2 ] || {
386  echo_i "ns3 $udp3 expected 2"
387  ret=1
388}
389if [ $ret != 0 ]; then echo_i "failed"; fi
390status=$((status + ret))
391
392echo_i "checking TCP message counts"
393ret=0
394[ $tcp1 -eq 0 ] || {
395  echo_i "ns1 $tcp1 expected 0"
396  ret=1
397}
398[ $tcp2 -eq 0 ] || {
399  echo_i "ns2 $tcp2 expected 0"
400  ret=1
401}
402[ $tcp3 -eq 0 ] || {
403  echo_i "ns3 $tcp3 expected 0"
404  ret=1
405}
406if [ $ret != 0 ]; then echo_i "failed"; fi
407status=$((status + ret))
408
409echo_i "checking AUTH_QUERY message counts"
410ret=0
411[ $aq1 -eq 0 ] || {
412  echo_i "ns1 $aq1 exepcted 0"
413  ret=1
414}
415[ $aq2 -eq 0 ] || {
416  echo_i "ns2 $aq2 expected 0"
417  ret=1
418}
419[ $aq3 -eq 0 ] || {
420  echo_i "ns3 $aq3 expected 0"
421  ret=1
422}
423if [ $ret != 0 ]; then echo_i "failed"; fi
424status=$((status + ret))
425
426echo_i "checking AUTH_RESPONSE message counts"
427ret=0
428[ $ar1 -eq 0 ] || {
429  echo_i "ns1 $ar1 expected 0"
430  ret=1
431}
432[ $ar2 -eq 0 ] || {
433  echo_i "ns2 $ar2 expected 0"
434  ret=1
435}
436[ $ar3 -eq 0 ] || {
437  echo_i "ns3 $ar3 expected 0"
438  ret=1
439}
440if [ $ret != 0 ]; then echo_i "failed"; fi
441status=$((status + ret))
442
443echo_i "checking CLIENT_QUERY message counts"
444ret=0
445[ $cq1 -eq 0 ] || {
446  echo_i "ns1 $cq1 expected 0"
447  ret=1
448}
449[ $cq2 -eq 0 ] || {
450  echo_i "ns2 $cq2 expected 0"
451  ret=1
452}
453[ $cq3 -eq 1 ] || {
454  echo_i "ns3 $cq3 expected 1"
455  ret=1
456}
457if [ $ret != 0 ]; then echo_i "failed"; fi
458status=$((status + ret))
459
460echo_i "checking CLIENT_RESPONSE message counts"
461ret=0
462[ $cr1 -eq 0 ] || {
463  echo_i "ns1 $cr1 expected 0"
464  ret=1
465}
466[ $cr2 -eq 0 ] || {
467  echo_i "ns2 $cr2 expected 0"
468  ret=1
469}
470[ $cr3 -eq 1 ] || {
471  echo_i "ns3 $cr3 expected 1"
472  ret=1
473}
474if [ $ret != 0 ]; then echo_i "failed"; fi
475status=$((status + ret))
476
477echo_i "checking RESOLVER_QUERY message counts"
478ret=0
479[ $rq1 -eq 0 ] || {
480  echo_i "ns1 $rq1 expected 0"
481  ret=1
482}
483[ $rq2 -eq 0 ] || {
484  echo_i "ns2 $rq2 expected 0"
485  ret=1
486}
487[ $rq3 -eq 0 ] || {
488  echo_i "ns3 $rq3 expected 0"
489  ret=1
490}
491if [ $ret != 0 ]; then echo_i "failed"; fi
492status=$((status + ret))
493
494echo_i "checking RESOLVER_RESPONSE message counts"
495ret=0
496[ $rr1 -eq 0 ] || {
497  echo_i "ns1 $rr1 expected 0"
498  ret=1
499}
500[ $rr2 -eq 0 ] || {
501  echo_i "ns2 $rr2 expected 0"
502  ret=1
503}
504[ $rr3 -eq 0 ] || {
505  echo_i "ns3 $rr3 expected 0"
506  ret=1
507}
508if [ $ret != 0 ]; then echo_i "failed"; fi
509status=$((status + ret))
510
511echo_i "checking UPDATE_QUERY message counts"
512ret=0
513[ $uq1 -eq 0 ] || {
514  echo_i "ns1 $uq1 expected 0"
515  ret=1
516}
517[ $uq2 -eq 1 ] || {
518  echo_i "ns2 $uq2 expected 1"
519  ret=1
520}
521[ $uq3 -eq 0 ] || {
522  echo_i "ns3 $uq3 expected 0"
523  ret=1
524}
525if [ $ret != 0 ]; then echo_i "failed"; fi
526status=$((status + ret))
527
528echo_i "checking UPDATE_RESPONSE message counts"
529ret=0
530[ $ur1 -eq 0 ] || {
531  echo_i "ns1 $ur1 expected 0"
532  ret=1
533}
534[ $ur2 -eq 1 ] || {
535  echo_i "ns2 $ur2 expected 1"
536  ret=1
537}
538[ $ur3 -eq 0 ] || {
539  echo_i "ns3 $ur3 expected 0"
540  ret=1
541}
542if [ $ret != 0 ]; then echo_i "failed"; fi
543status=$((status + ret))
544
545echo_i "checking whether destination UDP port is logged for client queries"
546ret=0
547$DNSTAPREAD ns3/dnstap.out.save | grep -Eq "CQ [0-9:.]+ -> 10.53.0.3:${PORT} UDP" || ret=1
548if [ $ret != 0 ]; then echo_i "failed"; fi
549status=$((status + ret))
550
551HAS_PYYAML=0
552if [ -x "$PYTHON" ]; then
553  $PYTHON -c "import yaml" 2>/dev/null && HAS_PYYAML=1
554fi
555
556if [ $HAS_PYYAML -ne 0 ]; then
557  echo_i "checking dnstap-read YAML output"
558  ret=0
559  {
560    $PYTHON ydump.py "$DNSTAPREAD" "ns3/dnstap.out.save" >ydump.out || ret=1
561  } | cat_i
562  if [ $ret != 0 ]; then echo_i "failed"; fi
563  status=$((status + ret))
564fi
565
566echo_i "checking dnstap-read hex output"
567ret=0
568hex=$($DNSTAPREAD -x ns3/dnstap.out | tail -1)
569echo $hex | $WIRETEST >dnstap.hex
570grep 'status: NOERROR' dnstap.hex >/dev/null 2>&1 || ret=1
571grep 'ANSWER: 3, AUTHORITY: 1' dnstap.hex >/dev/null 2>&1 || ret=1
572if [ $ret != 0 ]; then echo_i "failed"; fi
573status=$((status + ret))
574
575if [ -n "$FSTRM_CAPTURE" ]; then
576  $DIG $DIGOPTS @10.53.0.4 a.example >dig.out
577
578  # send an UPDATE to ns4
579  $NSUPDATE <<-EOF >nsupdate.out 2>&1 && ret=1
580	server 10.53.0.4 ${PORT}
581	zone example
582	update add b.example 3600 in a 10.10.10.10
583	send
584EOF
585  grep "update failed: NOTAUTH" nsupdate.out >/dev/null || ret=1
586
587  echo_i "checking unix socket message counts"
588  sleep 2
589  retry_quiet 5 dnstap_data_ready $fstrm_capture_pid dnstap.out 450 || {
590    echo_i "dnstap output file smaller than expected"
591    ret=1
592  }
593  if [ $ret != 0 ]; then echo_i "failed"; fi
594  status=$((status + ret))
595  kill $fstrm_capture_pid
596  wait
597  udp4=$($DNSTAPREAD dnstap.out | grep "UDP " | wc -l)
598  tcp4=$($DNSTAPREAD dnstap.out | grep "TCP " | wc -l)
599  aq4=$($DNSTAPREAD dnstap.out | grep "AQ " | wc -l)
600  ar4=$($DNSTAPREAD dnstap.out | grep "AR " | wc -l)
601  cq4=$($DNSTAPREAD dnstap.out | grep "CQ " | wc -l)
602  cr4=$($DNSTAPREAD dnstap.out | grep "CR " | wc -l)
603  rq4=$($DNSTAPREAD dnstap.out | grep "RQ " | wc -l)
604  rr4=$($DNSTAPREAD dnstap.out | grep "RR " | wc -l)
605  uq4=$($DNSTAPREAD dnstap.out | grep "UQ " | wc -l)
606  ur4=$($DNSTAPREAD dnstap.out | grep "UR " | wc -l)
607
608  echo_i "checking UDP message counts"
609  ret=0
610  [ $udp4 -eq 4 ] || {
611    echo_i "ns4 $udp4 expected 4"
612    ret=1
613  }
614  if [ $ret != 0 ]; then echo_i "failed"; fi
615  status=$((status + ret))
616
617  echo_i "checking TCP message counts"
618  ret=0
619  [ $tcp4 -eq 0 ] || {
620    echo_i "ns4 $tcp4 expected 0"
621    ret=1
622  }
623  if [ $ret != 0 ]; then echo_i "failed"; fi
624  status=$((status + ret))
625
626  echo_i "checking AUTH_QUERY message counts"
627  ret=0
628  [ $aq4 -eq 0 ] || {
629    echo_i "ns4 $aq4 expected 0"
630    ret=1
631  }
632  if [ $ret != 0 ]; then echo_i "failed"; fi
633  status=$((status + ret))
634
635  echo_i "checking AUTH_RESPONSE message counts"
636  ret=0
637  [ $ar4 -eq 0 ] || {
638    echo_i "ns4 $ar4 expected 0"
639    ret=1
640  }
641  if [ $ret != 0 ]; then echo_i "failed"; fi
642  status=$((status + ret))
643
644  echo_i "checking CLIENT_QUERY message counts"
645  ret=0
646  [ $cq4 -eq 1 ] || {
647    echo_i "ns4 $cq4 expected 1"
648    ret=1
649  }
650  if [ $ret != 0 ]; then echo_i "failed"; fi
651  status=$((status + ret))
652
653  echo_i "checking CLIENT_RESPONSE message counts"
654  ret=0
655  [ $cr4 -eq 1 ] || {
656    echo_i "ns4 $cr4 expected 1"
657    ret=1
658  }
659  if [ $ret != 0 ]; then echo_i "failed"; fi
660  status=$((status + ret))
661
662  echo_i "checking RESOLVER_QUERY message counts"
663  ret=0
664  [ $rq4 -eq 0 ] || {
665    echo_i "ns4 $rq4 expected 0"
666    ret=1
667  }
668  if [ $ret != 0 ]; then echo_i "failed"; fi
669  status=$((status + ret))
670
671  echo_i "checking RESOLVER_RESPONSE message counts"
672  ret=0
673  [ $rr4 -eq 0 ] || {
674    echo_i "ns4 $rr4 expected 0"
675    ret=1
676  }
677
678  echo_i "checking UPDATE_QUERY message counts"
679  ret=0
680  [ $uq4 -eq 1 ] || {
681    echo_i "ns4 $uq4 expected 1"
682    ret=1
683  }
684  if [ $ret != 0 ]; then echo_i "failed"; fi
685  status=$((status + ret))
686
687  echo_i "checking UPDATE_RESPONSE message counts"
688  ret=0
689  [ $ur4 -eq 1 ] || {
690    echo_i "ns4 $ur4 expected 1"
691    ret=1
692  }
693  if [ $ret != 0 ]; then echo_i "failed"; fi
694  status=$((status + ret))
695
696  mv dnstap.out dnstap.out.save
697
698  echo_i "restarting fstrm_capture"
699  $FSTRM_CAPTURE -t protobuf:dnstap.Dnstap -u ns4/dnstap.out \
700    -w dnstap.out >fstrm_capture.out.2 2>&1 &
701  fstrm_capture_pid=$!
702  wait_for_log 10 "socket path ns4/dnstap.out" fstrm_capture.out.2 || {
703    echo_i "failed"
704    ret=1
705  }
706  $RNDCCMD -s 10.53.0.4 dnstap -reopen | sed 's/^/ns4 /' | cat_i
707  $DIG $DIGOPTS @10.53.0.4 a.example >dig.out
708
709  echo_i "checking reopened unix socket message counts"
710  sleep 2
711  retry_quiet 5 dnstap_data_ready $fstrm_capture_pid dnstap.out 270 || {
712    echo_i "dnstap output file smaller than expected"
713    ret=1
714  }
715  if [ $ret != 0 ]; then echo_i "failed"; fi
716  status=$((status + ret))
717  kill $fstrm_capture_pid
718  wait
719  udp4=$($DNSTAPREAD dnstap.out | grep "UDP " | wc -l)
720  tcp4=$($DNSTAPREAD dnstap.out | grep "TCP " | wc -l)
721  aq4=$($DNSTAPREAD dnstap.out | grep "AQ " | wc -l)
722  ar4=$($DNSTAPREAD dnstap.out | grep "AR " | wc -l)
723  cq4=$($DNSTAPREAD dnstap.out | grep "CQ " | wc -l)
724  cr4=$($DNSTAPREAD dnstap.out | grep "CR " | wc -l)
725  rq4=$($DNSTAPREAD dnstap.out | grep "RQ " | wc -l)
726  rr4=$($DNSTAPREAD dnstap.out | grep "RR " | wc -l)
727  uq4=$($DNSTAPREAD dnstap.out | grep "UQ " | wc -l)
728  ur4=$($DNSTAPREAD dnstap.out | grep "UR " | wc -l)
729
730  echo_i "checking UDP message counts"
731  ret=0
732  [ $udp4 -eq 2 ] || {
733    echo_i "ns4 $udp4 expected 2"
734    ret=1
735  }
736  if [ $ret != 0 ]; then echo_i "failed"; fi
737  status=$((status + ret))
738
739  echo_i "checking TCP message counts"
740  ret=0
741  [ $tcp4 -eq 0 ] || {
742    echo_i "ns4 $tcp4 expected 0"
743    ret=1
744  }
745  if [ $ret != 0 ]; then echo_i "failed"; fi
746  status=$((status + ret))
747
748  echo_i "checking AUTH_QUERY message counts"
749  ret=0
750  [ $aq4 -eq 0 ] || {
751    echo_i "ns4 $aq4 expected 0"
752    ret=1
753  }
754  if [ $ret != 0 ]; then echo_i "failed"; fi
755  status=$((status + ret))
756
757  echo_i "checking AUTH_RESPONSE message counts"
758  ret=0
759  [ $ar4 -eq 0 ] || {
760    echo_i "ns4 $ar4 expected 0"
761    ret=1
762  }
763  if [ $ret != 0 ]; then echo_i "failed"; fi
764  status=$((status + ret))
765
766  echo_i "checking CLIENT_QUERY message counts"
767  ret=0
768  [ $cq4 -eq 1 ] || {
769    echo_i "ns4 $cq4 expected 1"
770    ret=1
771  }
772  if [ $ret != 0 ]; then echo_i "failed"; fi
773  status=$((status + ret))
774
775  echo_i "checking CLIENT_RESPONSE message counts"
776  ret=0
777  [ $cr4 -eq 1 ] || {
778    echo_i "ns4 $cr4 expected 1"
779    ret=1
780  }
781  if [ $ret != 0 ]; then echo_i "failed"; fi
782  status=$((status + ret))
783
784  echo_i "checking RESOLVER_QUERY message counts"
785  ret=0
786  [ $rq4 -eq 0 ] || {
787    echo_i "ns4 $rq4 expected 0"
788    ret=1
789  }
790  if [ $ret != 0 ]; then echo_i "failed"; fi
791  status=$((status + ret))
792
793  echo_i "checking RESOLVER_RESPONSE message counts"
794  ret=0
795  [ $rr4 -eq 0 ] || {
796    echo_i "ns4 $rr4 expected 0"
797    ret=1
798  }
799
800  echo_i "checking UPDATE_QUERY message counts"
801  ret=0
802  [ $uq4 -eq 0 ] || {
803    echo_i "ns4 $uq4 expected 0"
804    ret=1
805  }
806  if [ $ret != 0 ]; then echo_i "failed"; fi
807  status=$((status + ret))
808
809  echo_i "checking UPDATE_RESPONSE message counts"
810  ret=0
811  [ $ur4 -eq 0 ] || {
812    echo_i "ns4 $ur4 expected 0"
813    ret=1
814  }
815  if [ $ret != 0 ]; then echo_i "failed"; fi
816  status=$((status + ret))
817fi
818
819echo_i "checking large packet printing"
820ret=0
821# Expect one occurrence of "opcode: QUERY" below "reponse_message_data" and
822# another one below "response_message".
823lines=$($DNSTAPREAD -y large-answer.fstrm | grep -c "opcode: QUERY")
824[ $lines -eq 2 ] || ret=1
825if [ $ret != 0 ]; then echo_i "failed"; fi
826status=$((status + ret))
827
828_test_dnstap_roll() (
829  ip="$1"
830  ns="$2"
831  n="$3"
832
833  $RNDCCMD -s "${ip}" dnstap -roll "${n}" | sed "s/^/${ns} /" | cat_i \
834    && files=$(find "$ns" -name "dnstap.out.[0-9]" | wc -l) \
835    && test "$files" -eq "${n}" && test "$files" -ge "1" || return 1
836)
837
838test_dnstap_roll() {
839  echo_i "checking 'rndc -roll $4' ($1)"
840  ret=0
841
842  try=0
843  while test $try -lt 12; do
844    touch "$3/dnstap.out.$try"
845    try=$((try + 1))
846  done
847
848  _repeat 10 _test_dnstap_roll $2 $3 $4 || ret=1
849  if [ $ret != 0 ]; then echo_i "failed"; fi
850  status=$((status + ret))
851}
852
853start_server --noclean --restart --port "${PORT}" ns3
854test_dnstap_roll "no versions" 10.53.0.3 ns3 6
855test_dnstap_roll "no versions" 10.53.0.3 ns3 3
856test_dnstap_roll "no versions" 10.53.0.3 ns3 1
857
858start_server --noclean --restart --port "${PORT}" ns2
859test_dnstap_roll "versions" 10.53.0.2 ns2 6
860test_dnstap_roll "versions" 10.53.0.2 ns2 3
861test_dnstap_roll "versions" 10.53.0.2 ns2 1
862
863echo_i "exit status: $status"
864[ "$status" -eq 0 ] || exit 1
865