Home | History | Annotate | Line # | Download | only in reclimit
      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