1# #-- ip_ratelimit.test --#
2# source the master var file when it's there
3[ -f ../.tpkg.var.master ] && source ../.tpkg.var.master
4# use .tpkg.var.test for in test variable passing
5[ -f .tpkg.var.test ] && source .tpkg.var.test
6
7PRE="../.."
8. ../common.sh
9
10get_make
11(cd $PRE; $MAKE streamtcp)
12
13# These tests rely on second time precision. To combat false negatives the
14# tests run multiple times and we allow 1/3 of the runs to fail.
15total_runs=6
16success_threshold=4  # 2/3*total_runs
17
18if dig -h 2>&1 | grep "cookie" >/dev/null; then
19	nocookie="+nocookie"
20else
21	nocookie=""
22fi
23
24echo "> First get a valid cookie"
25dig @127.0.0.1 -p $UNBOUND_PORT +ednsopt=10:0102030405060708 $nocookie +tcp +retry=0 +time=1 test. TXT >outfile 2>&1
26if test "$?" -ne 0; then
27	echo "exit status not OK"
28	echo "> cat logfiles"
29	cat outfile
30	cat unbound.log
31	echo "Not OK"
32	exit 1
33fi
34if test `grep "COOKIE: " outfile | wc -l` -ne 1; then
35	echo "Could not get cookie"
36	echo "> cat logfiles"
37	cat outfile
38	cat unbound.log
39	echo "Not OK"
40	exit 1
41fi
42cookie=`grep "COOKIE: " outfile | cut -d ' ' -f 3`
43
44successes=0
45echo "> Three parallel queries with backoff and cookie"
46# For this test we send three parallel queries. The ratelimit should be reached
47# for that second. We send a query to verify that there is no reply.
48# Then for the next second we again send three parallel queries and we expect
49# none of them to be allowed through because of the backoff logic that keeps
50# rolling the RATE_WINDOW based on demand.
51# Again we send another query but with a valid cookie and we expect to receive
52# an answer.
53for i in $(seq 1 $total_runs); do
54	# Try to hit limit
55	$PRE/streamtcp -nu -f 127.0.0.1@$UNBOUND_PORT test. TXT IN test. TXT IN test. TXT IN >outfile 2>&1
56	if test "$?" -ne 0; then
57		echo "exit status not OK"
58		echo "> cat logfiles"
59		cat outfile
60		cat unbound.log
61		echo "Not OK"
62		exit 1
63	fi
64	# Expect no answer because of limit
65	dig @127.0.0.1 -p $UNBOUND_PORT $nocookie +retry=0 +time=1 test. TXT >outfile 2>&1
66	if test "$?" -eq 0; then
67		continue
68	fi
69	# Try to keep limit
70	$PRE/streamtcp -nu -f 127.0.0.1@$UNBOUND_PORT test. TXT IN test. TXT IN test. TXT IN >outfile 2>&1
71	if test "$?" -ne 0; then
72		echo "exit status not OK"
73		echo "> cat logfiles"
74		cat outfile
75		cat unbound.log
76		echo "Not OK"
77		exit 1
78	fi
79	# Expect answer because of DNS cookie
80	dig @127.0.0.1 -p $UNBOUND_PORT +ednsopt=10:$cookie $nocookie +retry=0 +time=1 test. TXT >outfile 2>&1
81	if test "$?" -ne 0; then
82		continue
83	fi
84	((successes++))
85	# We don't have to wait for all the runs to complete if we know
86	# we passed the threshold.
87	if test $successes -ge $success_threshold; then
88		break
89	fi
90done
91
92if test $successes -ge $success_threshold; then
93	echo "Three parallel queries with backoff and cookie OK"
94else
95	echo "Three parallel queries with backoff and cookie NOT OK"
96	echo "> cat logfiles"
97	cat outfile
98	cat unbound.log
99	echo "Three parallel queries with backoff and cookie NOT OK"
100	exit 1
101fi
102
103echo "> Activating ip-ratelimit-cookie"
104echo "$PRE/unbound-control -c ub.conf set_option ip-ratelimit-cookie: 1"
105$PRE/unbound-control -c ub.conf set_option ip-ratelimit-cookie: 1
106if test $? -ne 0; then
107	echo "wrong exit value after success"
108	exit 1
109fi
110
111successes=0
112echo "> Three parallel queries with backoff and cookie with ip-ratelimit-cookie"
113# This is the exact same test as above with the exception that we don't expect
114# an answer on the last query because ip-ratelimit-cookie is now enabled.
115for i in $(seq 1 $total_runs); do
116	# Try to hit limit
117	$PRE/streamtcp -nu -f 127.0.0.1@$UNBOUND_PORT test. TXT IN test. TXT IN test. TXT IN >outfile 2>&1
118	if test "$?" -ne 0; then
119		echo "exit status not OK"
120		echo "> cat logfiles"
121		cat outfile
122		cat unbound.log
123		echo "Not OK"
124		exit 1
125	fi
126	# Expect no answer because of limit
127	dig @127.0.0.1 -p $UNBOUND_PORT $nocookie +retry=0 +time=1 test. TXT >outfile 2>&1
128	if test "$?" -eq 0; then
129		continue
130	fi
131	# Try to keep limit
132	$PRE/streamtcp -nu -f 127.0.0.1@$UNBOUND_PORT test. TXT IN test. TXT IN test. TXT IN >outfile 2>&1
133	if test "$?" -ne 0; then
134		echo "exit status not OK"
135		echo "> cat logfiles"
136		cat outfile
137		cat unbound.log
138		echo "Not OK"
139		exit 1
140	fi
141	# Expect no answer because of ip-ratelimit-cookie
142	dig @127.0.0.1 -p $UNBOUND_PORT +ednsopt=10:$cookie $nocookie +retry=0 +time=1 test. TXT >outfile 2>&1
143	if test "$?" -eq 0; then
144		continue
145	fi
146	((successes++))
147	# We don't have to wait for all the runs to complete if we know
148	# we passed the threshold.
149	if test $successes -ge $success_threshold; then
150		break
151	fi
152done
153
154if test $successes -ge $success_threshold; then
155	echo "Three parallel queries with backoff and cookie with ip-ratelimit-cookie OK"
156else
157	echo "Three parallel queries with backoff and cookie with ip-ratelimit-cookie NOT OK"
158	echo "> cat logfiles"
159	cat outfile
160	cat unbound.log
161	echo "Three parallel queries with backoff and cookie with ip-ratelimit-cookie NOT OK"
162	exit 1
163fi
164
165exit 0
166