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 14 set -e 15 16 . ../conf.sh 17 18 dig_with_opts() { 19 $DIG -p "${PORT}" +retries=0 "$@" 20 } 21 22 status=0 23 n=0 24 25 ns3_reset() { 26 $RNDC -c ../_common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} reconfig 2>&1 | sed 's/^/I:ns3 /' 27 $RNDC -c ../_common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} flush | sed 's/^/I:ns3 /' 28 } 29 30 ns3_flush() { 31 $RNDC -c ../_common/rndc.conf -s 10.53.0.3 -p ${CONTROLPORT} flush | sed 's/^/I:ns3 /' 32 } 33 34 ns3_sends_aaaa_queries() { 35 if grep "started AAAA fetch" ns3/named.run >/dev/null; then 36 return 0 37 else 38 return 1 39 fi 40 } 41 42 # Check whether the number of queries ans2 received from ns3 (this value is 43 # read from dig output stored in file $1) is as expected. The expected query 44 # count is variable: 45 # - if ns3 sends AAAA queries, the query count should equal $2, 46 # - if ns3 does not send AAAA queries, the query count should equal $3. 47 check_query_count() { 48 count1=$(sed 's/[^0-9]//g;' $1) 49 count2=$(sed 's/[^0-9]//g;' $2) 50 count=$((count1 + count2)) 51 #echo_i "count1=$count1 count2=$count2 count=$count" 52 expected_count_with_aaaa=$3 53 expected_count_without_aaaa=$4 54 55 if ns3_sends_aaaa_queries; then 56 expected_count=$expected_count_with_aaaa 57 else 58 expected_count=$expected_count_without_aaaa 59 fi 60 61 if [ $count -ne $expected_count ]; then 62 echo_i "count $count (actual) != $expected_count (expected)" 63 ret=1 64 fi 65 } 66 67 echo_i "set max-recursion-depth=12" 68 69 n=$((n + 1)) 70 echo_i "attempt excessive-depth lookup ($n)" 71 ret=0 72 echo "1000" >ans2/ans.limit 73 echo "1000" >ans4/ans.limit 74 dig_with_opts @10.53.0.2 reset >/dev/null || ret=1 75 dig_with_opts @10.53.0.4 reset >/dev/null || ret=1 76 dig_with_opts @10.53.0.3 indirect1.example.org >dig.out.1.test$n || ret=1 77 grep "status: SERVFAIL" dig.out.1.test$n >/dev/null || ret=1 78 dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1 79 dig_with_opts +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1 80 check_query_count dig.out.2.test$n dig.out.4.test$n 27 14 81 if [ $ret != 0 ]; then echo_i "failed"; fi 82 status=$((status + ret)) 83 84 n=$((n + 1)) 85 echo_i "attempt permissible lookup ($n)" 86 ret=0 87 echo "12" >ans2/ans.limit 88 echo "12" >ans4/ans.limit 89 ns3_reset 90 dig_with_opts @10.53.0.2 reset >/dev/null || ret=1 91 dig_with_opts @10.53.0.4 reset >/dev/null || ret=1 92 dig_with_opts @10.53.0.3 indirect2.example.org >dig.out.1.test$n || ret=1 93 grep "status: NOERROR" dig.out.1.test$n >/dev/null || ret=1 94 dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1 95 dig_with_opts +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1 96 check_query_count dig.out.2.test$n dig.out.4.test$n 50 26 97 if [ $ret != 0 ]; then echo_i "failed"; fi 98 status=$((status + ret)) 99 100 echo_i "set max-recursion-depth=5" 101 102 n=$((n + 1)) 103 echo_i "attempt excessive-depth lookup ($n)" 104 ret=0 105 echo "12" >ans2/ans.limit 106 cp ns3/named2.conf ns3/named.conf 107 ns3_reset 108 dig_with_opts @10.53.0.2 reset >/dev/null || ret=1 109 dig_with_opts @10.53.0.4 reset >/dev/null || ret=1 110 dig_with_opts @10.53.0.3 indirect3.example.org >dig.out.1.test$n || ret=1 111 grep "status: SERVFAIL" dig.out.1.test$n >/dev/null || ret=1 112 dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1 113 dig_with_opts +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1 114 check_query_count dig.out.2.test$n dig.out.4.test$n 13 7 115 if [ $ret != 0 ]; then echo_i "failed"; fi 116 status=$((status + ret)) 117 118 n=$((n + 1)) 119 echo_i "attempt permissible lookup ($n)" 120 ret=0 121 echo "5" >ans2/ans.limit 122 echo "5" >ans4/ans.limit 123 ns3_reset 124 dig_with_opts @10.53.0.2 reset >/dev/null || ret=1 125 dig_with_opts @10.53.0.4 reset >/dev/null || ret=1 126 dig_with_opts @10.53.0.3 indirect4.example.org >dig.out.1.test$n || ret=1 127 grep "status: NOERROR" dig.out.1.test$n >/dev/null || ret=1 128 dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1 129 dig_with_opts +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1 130 check_query_count dig.out.2.test$n dig.out.4.test$n 22 12 131 if [ $ret != 0 ]; then echo_i "failed"; fi 132 status=$((status + ret)) 133 134 echo_i "set max-recursion-depth=100, max-recursion-queries=50" 135 136 n=$((n + 1)) 137 echo_i "attempt excessive-queries lookup ($n)" 138 ret=0 139 echo "13" >ans2/ans.limit 140 echo "13" >ans4/ans.limit 141 cp ns3/named3.conf ns3/named.conf 142 ns3_reset 143 dig_with_opts @10.53.0.2 reset >/dev/null || ret=1 144 dig_with_opts @10.53.0.4 reset >/dev/null || ret=1 145 dig_with_opts @10.53.0.3 indirect5.example.org >dig.out.1.test$n || ret=1 146 if ns3_sends_aaaa_queries; then 147 grep "status: SERVFAIL" dig.out.1.test$n >/dev/null || ret=1 148 fi 149 dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1 150 dig_with_opts +short @10.53.0.4 count txt >dig.out.4.test$n || ret=1 151 eval count=$(cat dig.out.2.test$n) 152 [ $count -le 50 ] || { 153 ret=1 154 echo_i "count ($count) !<= 50" 155 } 156 if [ $ret != 0 ]; then echo_i "failed"; fi 157 status=$((status + ret)) 158 159 n=$((n + 1)) 160 echo_i "attempt permissible lookup ($n)" 161 ret=0 162 echo "12" >ans2/ans.limit 163 ns3_reset 164 dig_with_opts @10.53.0.2 reset >/dev/null || ret=1 165 dig_with_opts @10.53.0.3 indirect6.example.org >dig.out.1.test$n || ret=1 166 grep "status: NOERROR" dig.out.1.test$n >/dev/null || ret=1 167 dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1 168 eval count=$(cat dig.out.2.test$n) 169 [ $count -le 50 ] || { 170 ret=1 171 echo_i "count ($count) !<= 50" 172 } 173 if [ $ret != 0 ]; then echo_i "failed"; fi 174 status=$((status + ret)) 175 176 echo_i "set max-recursion-depth=100, max-recursion-queries=40" 177 178 n=$((n + 1)) 179 echo_i "attempt excessive-queries lookup ($n)" 180 ret=0 181 echo "11" >ans2/ans.limit 182 cp ns3/named4.conf ns3/named.conf 183 ns3_reset 184 dig_with_opts @10.53.0.2 reset >/dev/null || ret=1 185 dig_with_opts @10.53.0.3 indirect7.example.org >dig.out.1.test$n || ret=1 186 if ns3_sends_aaaa_queries; then 187 grep "status: SERVFAIL" dig.out.1.test$n >/dev/null || ret=1 188 fi 189 dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1 190 eval count=$(cat dig.out.2.test$n) 191 [ $count -le 40 ] || { 192 ret=1 193 echo_i "count ($count) !<= 40" 194 } 195 if [ $ret != 0 ]; then echo_i "failed"; fi 196 status=$((status + ret)) 197 198 n=$((n + 1)) 199 echo_i "attempt permissible lookup ($n)" 200 ret=0 201 echo "9" >ans2/ans.limit 202 ns3_reset 203 dig_with_opts @10.53.0.2 reset >/dev/null || ret=1 204 dig_with_opts @10.53.0.3 indirect8.example.org >dig.out.1.test$n || ret=1 205 grep "status: NOERROR" dig.out.1.test$n >/dev/null || ret=1 206 dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1 207 eval count=$(cat dig.out.2.test$n) 208 [ $count -le 40 ] || { 209 ret=1 210 echo_i "count ($count) !<= 40" 211 } 212 if [ $ret != 0 ]; then echo_i "failed"; fi 213 status=$((status + ret)) 214 215 n=$((n + 1)) 216 echo_i "attempting NS explosion ($n)" 217 ret=0 218 ns3_reset 219 dig_with_opts @10.53.0.2 reset >/dev/null || ret=1 220 dig_with_opts +short @10.53.0.3 ns1.1.example.net >dig.out.1.test$n || ret=1 221 dig_with_opts +short @10.53.0.2 count txt >dig.out.2.test$n || ret=1 222 eval count=$(cat dig.out.2.test$n) 223 [ $count -lt 50 ] || ret=1 224 dig_with_opts +short @10.53.0.7 count txt >dig.out.3.test$n || ret=1 225 eval count=$(cat dig.out.3.test$n) 226 [ $count -lt 50 ] || { 227 ret=1 228 echo_i "count ($count) !<= 50" 229 } 230 if [ $ret != 0 ]; then echo_i "failed"; fi 231 status=$((status + ret)) 232 233 n=$((n + 1)) 234 echo_i "checking RRset that exceeds max-records-per-type ($n)" 235 ret=0 236 dig_with_opts @10.53.0.3 biganswer.big >dig.out.1.test$n || ret=1 237 grep 'status: SERVFAIL' dig.out.1.test$n >/dev/null || ret=1 238 239 msg="error adding 'biganswer.big/A' in './IN' (cache): too many records (must not exceed 100)" 240 wait_for_log 10 "$msg" ns3/named.run || ret=1 241 if [ $ret != 0 ]; then echo_i "failed"; fi 242 status=$((status + ret)) 243 244 cp ns3/named5.conf ns3/named.conf 245 ns3_reset 246 dig_with_opts @10.53.0.3 biganswer.big >dig.out.2.test$n || ret=1 247 grep 'status: NOERROR' dig.out.2.test$n >/dev/null || ret=1 248 if [ $ret != 0 ]; then echo_i "failed"; fi 249 status=$((status + ret)) 250 251 check_manytypes() ( 252 i=$1 253 name=$2 254 type=$3 255 expected=$4 256 exname=$5 257 extype=$6 258 ttl=$7 259 neq_ttl=$8 260 261 if ! dig_with_opts @10.53.0.3 IN "$type" "$name" >"dig.out.$i.$type.test$n"; then 262 exit 1 263 fi 264 265 if ! grep 'status: '"${expected}"'' "dig.out.$i.$type.test$n" >/dev/null; then 266 exit 1 267 fi 268 269 if [ -n "$ttl" ] && ! grep -q "^$exname.[[:space:]]*${ttl}[[:space:]]*IN[[:space:]]*$extype" "dig.out.$i.$type.test$n"; then 270 exit 1 271 fi 272 273 if [ -n "${neq_ttl}" ] && grep -q "^$exname.[[:space:]]*${neq_ttl}[[:space:]]*IN[[:space:]]*$type" "dig.out.$i.$type.test$n"; then 274 exit 1 275 fi 276 277 exit 0 278 ) 279 280 n=$((n + 1)) 281 ret=0 282 echo_i "checking that priority names under the max-types-per-name limit get cached ($n)" 283 284 # Query for NXDOMAIN for items on our priority list - these should get cached 285 for rrtype in AAAA MX NS; do 286 check_manytypes 1 manytypes.big "${rrtype}" NOERROR big SOA 120 || ret=1 287 done 288 # Wait at least 1 second 289 for rrtype in AAAA MX NS; do 290 check_manytypes 2 manytypes.big "${rrtype}" NOERROR big SOA "" 120 || ret=1 291 done 292 293 if [ $ret -ne 0 ]; then echo_i "failed"; fi 294 status=$((status + ret)) 295 if [ $status -ne 0 ]; then exit 1; fi 296 297 ns3_flush 298 299 n=$((n + 1)) 300 ret=0 301 echo_i "checking that NXDOMAIN names under the max-types-per-name limit get cached ($n)" 302 303 # Query for 10 NXDOMAIN types 304 for ntype in $(seq 65270 65279); do 305 check_manytypes 1 manytypes.big "TYPE${ntype}" NOERROR big SOA 120 || ret=1 306 done 307 # Wait at least 1 second 308 sleep 1 309 # Query for 10 NXDOMAIN types again - these should be cached 310 for ntype in $(seq 65270 65279); do 311 check_manytypes 2 manytypes.big "TYPE${ntype}" NOERROR big SOA "" 120 || ret=1 312 done 313 314 if [ $ret -ne 0 ]; then echo_i "failed"; fi 315 status=$((status + ret)) 316 if [ $status -ne 0 ]; then exit 1; fi 317 318 n=$((n + 1)) 319 ret=0 320 echo_i "checking that existing names under the max-types-per-name limit get cached ($n)" 321 322 # Limited to 10 types - these should be cached and the previous record should be evicted 323 for ntype in $(seq 65280 65289); do 324 check_manytypes 1 manytypes.big "TYPE${ntype}" NOERROR manytypes.big "TYPE${ntype}" 120 || ret=1 325 done 326 # Wait at least one second 327 sleep 1 328 # Limited to 10 types - these should be cached 329 for ntype in $(seq 65280 65289); do 330 check_manytypes 2 manytypes.big "TYPE${ntype}" NOERROR manytypes.big "TYPE${ntype}" "" 120 || ret=1 331 done 332 333 if [ $ret -ne 0 ]; then echo_i "failed"; fi 334 status=$((status + ret)) 335 if [ $status -ne 0 ]; then exit 1; fi 336 337 n=$((n + 1)) 338 ret=0 339 echo_i "checking that NXDOMAIN names over the max-types-per-name limit don't get cached ($n)" 340 341 # Query for 10 NXDOMAIN types 342 for ntype in $(seq 65270 65279); do 343 check_manytypes 1 manytypes.big "TYPE${ntype}" NOERROR big SOA 0 || ret=1 344 done 345 # Wait at least 1 second 346 sleep 1 347 # Query for 10 NXDOMAIN types again - these should not be cached 348 for ntype in $(seq 65270 65279); do 349 check_manytypes 2 manytypes.big "TYPE${ntype}" NOERROR big SOA 0 || ret=1 350 done 351 352 if [ $ret -ne 0 ]; then echo_i "failed"; fi 353 status=$((status + ret)) 354 if [ $status -ne 0 ]; then exit 1; fi 355 356 n=$((n + 1)) 357 ret=0 358 echo_i "checking that priority NXDOMAIN names over the max-types-per-name limit get cached ($n)" 359 360 # Query for NXDOMAIN for items on our priority list - these should get cached 361 for rrtype in AAAA MX NS; do 362 check_manytypes 1 manytypes.big "${rrtype}" NOERROR big SOA 120 || ret=1 363 done 364 # Wait at least 1 second 365 for rrtype in AAAA MX NS; do 366 check_manytypes 2 manytypes.big "${rrtype}" NOERROR big SOA "" 120 || ret=1 367 done 368 369 if [ $ret -ne 0 ]; then echo_i "failed"; fi 370 status=$((status + ret)) 371 if [ $status -ne 0 ]; then exit 1; fi 372 373 n=$((n + 1)) 374 ret=0 375 echo_i "checking that priority name over the max-types-per-name get cached ($n)" 376 377 # Query for an item on our priority list - it should get cached 378 check_manytypes 1 manytypes.big "A" NOERROR manytypes.big A 120 || ret=1 379 # Wait at least 1 second 380 sleep 1 381 # Query the same name again - it should be in the cache 382 check_manytypes 2 manytypes.big "A" NOERROR big manytypes.A "" 120 || ret=1 383 384 if [ $ret -ne 0 ]; then echo_i "failed"; fi 385 status=$((status + ret)) 386 if [ $status -ne 0 ]; then exit 1; fi 387 388 ns3_flush 389 390 n=$((n + 1)) 391 ret=0 392 echo_i "checking that priority name over the max-types-per-name don't get evicted ($n)" 393 394 # Query for an item on our priority list - it should get cached 395 check_manytypes 1 manytypes.big "A" NOERROR manytypes.big A 120 || ret=1 396 # Query for 10 more types - this should not evict A record 397 for ntype in $(seq 65280 65289); do 398 check_manytypes 1 manytypes.big "TYPE${ntype}" NOERROR manytypes.big || ret=1 399 done 400 # Wait at least 1 second 401 sleep 1 402 # Query the same name again - it should be in the cache 403 check_manytypes 2 manytypes.big "A" NOERROR manytypes.big A "" 120 || ret=1 404 # This one was first in the list and should have been evicted 405 check_manytypes 2 manytypes.big "TYPE65280" NOERROR manytypes.big TYPE65280 120 || ret=1 406 407 if [ $ret -ne 0 ]; then echo_i "failed"; fi 408 status=$((status + ret)) 409 if [ $status -ne 0 ]; then exit 1; fi 410 411 ns3_flush 412 413 n=$((n + 1)) 414 ret=0 415 echo_i "checking that non-priority types cause eviction ($n)" 416 417 # Everything on top of that will cause the cache eviction 418 for ntype in $(seq 65280 65299); do 419 check_manytypes 1 manytypes.big "TYPE${ntype}" NOERROR manytypes.big "TYPE${ntype}" 120 || ret=1 420 done 421 # Wait at least one second 422 sleep 1 423 # These should have TTL != 120 now 424 for ntype in $(seq 65290 65299); do 425 check_manytypes 2 manytypes.big "TYPE${ntype}" NOERROR manytypes.big "TYPE${ntype}" "" 120 || ret=1 426 done 427 # These should have been evicted 428 for ntype in $(seq 65280 65289); do 429 check_manytypes 3 manytypes.big "TYPE${ntype}" NOERROR manytypes.big "TYPE${ntype}" 120 || ret=1 430 done 431 # These should have been evicted by the previous block 432 for ntype in $(seq 65290 65299); do 433 check_manytypes 4 manytypes.big "TYPE${ntype}" NOERROR manytypes.big "TYPE${ntype}" 120 || ret=1 434 done 435 436 if [ $ret -ne 0 ]; then echo_i "failed"; fi 437 status=$((status + ret)) 438 if [ $status -ne 0 ]; then exit 1; fi 439 440 ns3_flush 441 442 n=$((n + 1)) 443 ret=0 444 echo_i "checking that signed names under the max-types-per-name limit get cached ($n)" 445 446 # Go through the 10 items, this should result in 20 items (type + rrsig(type)) 447 for ntype in $(seq 65280 65289); do 448 check_manytypes 1 manytypes.signed "TYPE${ntype}" NOERROR manytypes.signed "TYPE${ntype}" 120 || ret=1 449 done 450 451 # Wait at least one second 452 sleep 1 453 454 # These should have TTL != 120 now 455 for ntype in $(seq 65285 65289); do 456 check_manytypes 2 manytypes.signed "TYPE${ntype}" NOERROR manytypes.signed "TYPE${ntype}" "" 120 || ret=1 457 done 458 459 # These should have been evicted 460 for ntype in $(seq 65280 65284); do 461 check_manytypes 3 manytypes.signed "TYPE${ntype}" NOERROR manytypes.signed "TYPE${ntype}" 120 || ret=1 462 done 463 464 # These should have been evicted by the previous block 465 for ntype in $(seq 65285 65289); do 466 check_manytypes 4 manytypes.signed "TYPE${ntype}" NOERROR manytypes.signed "TYPE${ntype}" 120 || ret=1 467 done 468 469 if [ $ret -ne 0 ]; then echo_i "failed"; fi 470 status=$((status + ret)) 471 if [ $status -ne 0 ]; then exit 1; fi 472 473 n=$((n + 1)) 474 ret=0 475 echo_i "checking that lifting the limit will allow everything to get cached ($n)" 476 477 # Lift the limit 478 cp ns3/named6.conf ns3/named.conf 479 ns3_reset 480 481 for ntype in $(seq 65280 65534); do 482 check_manytypes 1 manytypes.big "TYPE${ntype}" NOERROR manytypes.big "TYPE${ntype}" 120 || ret=1 483 done 484 # Wait at least one second 485 sleep 1 486 for ntype in $(seq 65280 65534); do 487 check_manytypes 2 manytypes.big "TYPE${ntype}" NOERROR manytypes.big "TYPE${ntype}" "" 120 || ret=1 488 done 489 490 if [ $ret -ne 0 ]; then echo_i "failed"; fi 491 status=$((status + ret)) 492 493 echo_i "exit status: $status" 494 [ $status -eq 0 ] || exit 1 495