# #-- ratelimit.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) # These tests rely on second time precision. To combat false negatives the # tests run multiple times and we allow 1/3 of the runs to fail. total_runs=6 success_threshold=4 # 2/3*total_runs successes=0 echo "> Three parallel queries" # For this test we send three parallel queries and we expect only one of them # to be allowed through each second. for i in $(seq 1 $total_runs); do $PRE/streamtcp -na -f 127.0.0.1@$UNBOUND_PORT www1.example.com. A IN www2.example.com. A IN www3.example.com. A IN >outfile 2>&1 if test "$?" -ne 0; then echo "exit status not OK" echo "> cat logfiles" cat outfile cat unbound.log echo "Not OK" exit 1 fi cat outfile if test `grep "rcode: SERVFAIL" outfile | wc -l` -eq 2; then ((successes++)) fi # We don't have to wait for all the runs to complete if we know # we passed the threshold. if test $successes -ge $success_threshold; then break fi sleep 1 done if test $successes -ge $success_threshold; then echo "Number of ratelimited queries OK for three parallel queries" else echo "Number of ratelimited queries not OK for three parallel queries" echo "> cat logfiles" cat outfile cat unbound.log echo "Number of ratelimited queries not OK for three parallel queries" exit 1 fi echo "> Activating ratelimit-factor" echo "$PRE/unbound-control -c ub.conf set_option ratelimit-factor: 3" $PRE/unbound-control -c ub.conf set_option ratelimit-factor: 3 if test $? -ne 0; then echo "wrong exit value after success" exit 1 fi slipped_through=0 echo "> Three parallel queries with ratelimit-factor" # For this test we send three parallel queries and we expect at least two of # them to be allowed through at a given second; one from the ratelimit itself # and one from the ratelimit-factor. for i in {1..10}; do $PRE/streamtcp -na -f 127.0.0.1@$UNBOUND_PORT www1.example.com. A IN www2.example.com. A IN www3.example.com. A IN >outfile 2>&1 if test "$?" -ne 0; then echo "exit status not OK" echo "> cat logfiles" cat outfile cat unbound.log echo "Not OK" exit 1 fi cat outfile if test `grep "rcode: SERVFAIL" outfile | wc -l` -lt 2; then slipped_through=1 break fi sleep 2 done if test $slipped_through -eq 0; then echo "ratelimit-factor did not work" echo "> cat logfiles" cat outfile cat unbound.log echo "ratelimit-factor did not work" exit 1 fi echo "ratelimit-factor OK" echo "> Disabling ratelimit-factor" echo "$PRE/unbound-control -c ub.conf set_option ratelimit-factor: 0" $PRE/unbound-control -c ub.conf set_option ratelimit-factor: 0 if test $? -ne 0; then echo "wrong exit value after success" exit 1 fi echo "> Activating ratelimit-backoff" echo "$PRE/unbound-control -c ub.conf set_option ratelimit-backoff: yes" $PRE/unbound-control -c ub.conf set_option ratelimit-backoff: yes if test $? -ne 0; then echo "wrong exit value after success" exit 1 fi successes=0 echo "> Three parallel queries with backoff" # For this test we send three parallel queries. The ratelimit should be reached # for that second. Then for the next second we again send three parallel # queries and we expect none of them to be allowed through because of the # backoff logic that keeps rolling the RATE_WINDOW based on demand. for i in $(seq 1 $total_runs); do $PRE/streamtcp -na -f 127.0.0.1@$UNBOUND_PORT www1.example.com. A IN www2.example.com. A IN www3.example.com. A IN >outfile 2>&1 if test "$?" -ne 0; then echo "exit status not OK" echo "> cat logfiles" cat outfile cat unbound.log echo "Not OK" exit 1 fi sleep 1 # Limit is reached; it should also be active for the next second $PRE/streamtcp -na -f 127.0.0.1@$UNBOUND_PORT www1.example.com. A IN www2.example.com. A IN www3.example.com. A IN >outfile 2>&1 if test "$?" -ne 0; then echo "exit status not OK" echo "> cat logfiles" cat outfile cat unbound.log echo "Not OK" exit 1 fi cat outfile if test `grep "rcode: SERVFAIL" outfile | wc -l` -eq 3; then ((successes++)) fi # We don't have to wait for all the runs to complete if we know # we passed the threshold. if test $successes -ge $success_threshold; then break fi done if test $successes -ge $success_threshold; then echo "three parallel queries with backoff OK" else echo "Number of ratelimited queries not OK for three parallel queries with backoff" echo "> cat logfiles" cat outfile cat unbound.log echo "Number of ratelimited queries not OK for three parallel queries with backoff" exit 1 fi echo "> Three parallel queries after backoff RATE_WINDOW" sleep 3 # Make sure the RATE_WINDOW is renewed # For this test we make three parallel queries after the RATE_WINDOW has passed # without any new demand and we expect at least one query to pass through. This # is to check that the backoff logic does not insist on past (outside of # RATE_WINDOW) limits. $PRE/streamtcp -na -f 127.0.0.1@$UNBOUND_PORT www1.example.com. A IN www2.example.com. A IN www3.example.com. A IN >outfile 2>&1 if test "$?" -ne 0; then echo "exit status not OK" echo "> cat logfiles" cat outfile cat unbound.log echo "Not OK" exit 1 fi cat outfile if test `grep "rcode: NOERROR" outfile | wc -l` -gt 0; then echo "Number of ratelimited queries OK for three parallel queries after backoff RATE_WINDOW" else echo "Number of ratelimited queries not OK for three parallel queries after backoff RATE_WINDOW" echo "> cat logfiles" cat outfile cat unbound.log echo "Number of ratelimited queries not OK for three parallel queries after backoff RATE_WINDOW" exit 1 fi exit 0