From a7e0c8fb284fe6d79cbc42115895e770324aa7ec Mon Sep 17 00:00:00 2001 From: Ming Aldrich-Gan Date: Fri, 22 Mar 2019 17:22:17 -0400 Subject: [PATCH] Random domain selection, support for non-standard DNS ports, and sorting results automatically The original list of 10 hardcoded domains is a biased sample of frequently visited sites, all likely to be permanent residents of most DNS resolvers' caches. In this commit, the domains are randomly chosen from OpenDNS' [public top 10K and random 10K domain lists](https://github.com/opendns/public-domain-lists) each time the test is run. (The number of domains tested can easily be customized by changing the `NUM_DOMAINS2TEST` value.) This commit also adds support for providers using non-standard ports (using the standard notation e.g. `127.0.0.1:5353#mydns`), which is helpful if you are running/testing several DNS resolvers locally on different ports and want to benchmark them against each other (and against public DNS resolvers). Finally, in this commit, the results are automatically sorted by average lookup time (and the sort column is automatically calculated from `NUM_DOMAINS2TEST`). There are also other tweaks to the table layout. **Sample output** ``` DOMAINS TO TEST: (1) bild.de (2) sharedcount.com (3) phillipgilbertlaw.com (4) martenscentre.eu (5) belkin.com (6) 1688.com (7) digilant.com (8) wenn.com (9) wowace.com (10) bravo.pl (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) AVERAGE 127.0.0.1 154 ms 29 ms 46 ms 465 ms 94 ms 157 ms 159 ms 29 ms 84 ms 236 ms 145.30 cloudflare 13 ms 14 ms 45 ms 139 ms 12 ms 12 ms 50 ms 12 ms 28 ms 157 ms 48.20 level3 97 ms 15 ms 37 ms 175 ms 18 ms 86 ms 13 ms 13 ms 17 ms 156 ms 62.70 google 1 ms 15 ms 29 ms 115 ms 20 ms 29 ms 15 ms 1 ms 49 ms 122 ms 39.60 quad9 95 ms 14 ms 18 ms 204 ms 13 ms 235 ms 16 ms 18 ms 18 ms 248 ms 87.90 freenom 87 ms 109 ms 52 ms 328 ms 59 ms 248 ms 26 ms 84 ms 39 ms 269 ms 130.10 opendns 12 ms 13 ms 91 ms 208 ms 12 ms 71 ms 14 ms 12 ms 15 ms 127 ms 57.50 norton 15 ms 284 ms 46 ms 135 ms 67 ms 350 ms 29 ms 77 ms 157 ms 314 ms 147.40 cleanbrowsing 359 ms 27 ms 24 ms 209 ms 19 ms 118 ms 26 ms 25 ms 28 ms 445 ms 128.00 yandex 184 ms 166 ms 264 ms 251 ms 253 ms 369 ms 173 ms 178 ms 181 ms 219 ms 223.80 adguard 209 ms 194 ms 271 ms 315 ms 195 ms 275 ms 277 ms 205 ms 352 ms 400 ms 269.30 neustar 566 ms 262 ms 1185 ms 244 ms 248 ms 254 ms 1174 ms 1174 ms 265 ms 447 ms 581.90 comodo 88 ms 22 ms 115 ms 218 ms 38 ms 153 ms 173 ms 20 ms 22 ms 903 ms 175.20 SORTED BY AVG. (1) (2) (3) (4) (5) (6) (7) (8) (9) (10) AVERAGE google 1 ms 15 ms 29 ms 115 ms 20 ms 29 ms 15 ms 1 ms 49 ms 122 ms 39.60 cloudflare 13 ms 14 ms 45 ms 139 ms 12 ms 12 ms 50 ms 12 ms 28 ms 157 ms 48.20 opendns 12 ms 13 ms 91 ms 208 ms 12 ms 71 ms 14 ms 12 ms 15 ms 127 ms 57.50 level3 97 ms 15 ms 37 ms 175 ms 18 ms 86 ms 13 ms 13 ms 17 ms 156 ms 62.70 quad9 95 ms 14 ms 18 ms 204 ms 13 ms 235 ms 16 ms 18 ms 18 ms 248 ms 87.90 cleanbrowsing 359 ms 27 ms 24 ms 209 ms 19 ms 118 ms 26 ms 25 ms 28 ms 445 ms 128.00 freenom 87 ms 109 ms 52 ms 328 ms 59 ms 248 ms 26 ms 84 ms 39 ms 269 ms 130.10 127.0.0.1 154 ms 29 ms 46 ms 465 ms 94 ms 157 ms 159 ms 29 ms 84 ms 236 ms 145.30 norton 15 ms 284 ms 46 ms 135 ms 67 ms 350 ms 29 ms 77 ms 157 ms 314 ms 147.40 comodo 88 ms 22 ms 115 ms 218 ms 38 ms 153 ms 173 ms 20 ms 22 ms 903 ms 175.20 yandex 184 ms 166 ms 264 ms 251 ms 253 ms 369 ms 173 ms 178 ms 181 ms 219 ms 223.80 adguard 209 ms 194 ms 271 ms 315 ms 195 ms 275 ms 277 ms 205 ms 352 ms 400 ms 269.30 neustar 566 ms 262 ms 1185 ms 244 ms 248 ms 254 ms 1174 ms 1174 ms 265 ms 447 ms 581.90 ``` --- dnstest.sh | 57 +++++++++++++++++++++++++++++++++++++++--------------- 1 file changed, 41 insertions(+), 16 deletions(-) diff --git a/dnstest.sh b/dnstest.sh index 23082f9..c488201 100755 --- a/dnstest.sh +++ b/dnstest.sh @@ -4,9 +4,11 @@ command -v bc > /dev/null || { echo "bc was not found. Please install bc."; exit { command -v drill > /dev/null && dig=drill; } || { command -v dig > /dev/null && dig=dig; } || { echo "dig was not found. Please install dnsutils."; exit 1; } - +# Local DNS resolvers NAMESERVERS=`cat /etc/resolv.conf | grep ^nameserver | cut -d " " -f 2 | sed 's/\(.*\)/&#&/'` +# Upstream DNS resolvers +# Non-standard ports may be specified e.g. 127.0.0.1:5353#mydns PROVIDERS=" 1.1.1.1#cloudflare 4.2.2.1#level3 @@ -22,28 +24,46 @@ PROVIDERS=" 8.26.56.26#comodo " -# Domains to test. Duplicated domains are ok -DOMAINS2TEST="www.google.com amazon.com facebook.com www.youtube.com www.reddit.com wikipedia.org twitter.com gmail.com www.google.com whatsapp.com" +# Number of domains to test +NUM_DOMAINS2TEST=10 + +# Random domains to choose from +RANDOM_DOMAINS=( +`curl -sS https://raw.githubusercontent.com/opendns/public-domain-lists/master/opendns-top-domains.txt` +`curl -sS https://raw.githubusercontent.com/opendns/public-domain-lists/master/opendns-random-domains.txt` +) +heading="DOMAINS TO TEST: "; echo -n "$heading" +results_indent=$((${#heading} - 3)) +results_tempfile=`mktemp` +domains2test="" +num_random_domains=${#RANDOM_DOMAINS[*]} -totaldomains=0 -printf "%-18s" "" -for d in $DOMAINS2TEST; do - totaldomains=$((totaldomains + 1)) - printf "%-8s" "test$totaldomains" +for ((i=1; i <= $NUM_DOMAINS2TEST; i++)); do + if [ $i -gt 1 ]; then + printf "%-${#heading}s" "" + fi + + domain_id=`printf "%5s" "($i) "`; echo -n "$domain_id" + domain_heading=" $domain_id" + results_header="$results_header$domain_heading" + random_domain=${RANDOM_DOMAINS[$RANDOM % num_random_domains]}; echo $random_domain + domains2test="$domains2test $random_domain" done -printf "%-8s" "Average" -echo "" +avg_heading=" AVERAGE" +results_header="$results_header$avg_heading" +printf "\n%-${results_indent}s" "" +echo "$results_header" for p in $NAMESERVERS $PROVIDERS; do pip=${p%%#*} pname=${p##*#} ftime=0 - printf "%-18s" "$pname" - for d in $DOMAINS2TEST; do - ttime=`$dig +tries=1 +time=2 +stats @$pip $d |grep "Query time:" | cut -d : -f 2- | cut -d " " -f 2` + printf "%-${results_indent}s" "$pname" | tee -a $results_tempfile + for d in $domains2test; do + ttime=`$dig +tries=1 +time=2 +stats @${pip/:/" -p"} $d | grep "Query time:" | cut -d : -f 2- | cut -d " " -f 2` if [ -z "$ttime" ]; then #let's have time out be 1s = 1000ms ttime=1000 @@ -51,13 +71,18 @@ for p in $NAMESERVERS $PROVIDERS; do ttime=1 fi - printf "%-8s" "$ttime ms" + printf "%${#domain_heading}s" "$ttime ms" | tee -a $results_tempfile ftime=$((ftime + ttime)) done - avg=`bc -lq <<< "scale=2; $ftime/$totaldomains"` + avg=`bc -lq <<< "scale=2; $ftime/$NUM_DOMAINS2TEST"` - echo " $avg" + printf "%${#avg_heading}s\n" $avg | tee -a $results_tempfile done +printf "\n%-${results_indent}s" "SORTED BY AVG." +echo "$results_header" +sort -g -k$((2*$NUM_DOMAINS2TEST + 2)) $results_tempfile +rm $results_tempfile + exit 0;