#!/bin/sh # # qtest: queries a set of DNS name servers and report the fastest ones # # Usage: qtest query server... # Example: qtest -n 3 "SOA fr" $(dig +short NS fr.) # # From: Joe Abley # Modified-by: Stephane Bortzmeyer # Settings max=1 verbose=0 # Some Unices like NetBSD are crazy enough to ship a dinosaurian # version of getopt, which cannot handle arguments with spaces! So, we # have a lot of work to work around this pre-babylonian limit. test_getopt() { getopt=$1 if [ ! -x $getopt ] && ! which $getopt > /dev/null 2>&1; then return 1 fi if [ "$($getopt -o '' -- 'a b')" = " -- 'a b'" ]; then return 0 else return 1 fi } if test_getopt getopt; then GETOPT=getopt else if test_getopt ggetopt; then GETOPT=ggetopt else if test_getopt /usr/pkg/bin/getopt; then # Last resort for NetBSD GETOPT=/usr/pkg/bin/getopt else echo "Cannot find a working getopt on this machine" > /dev/stderr exit 1 fi fi fi TEMP=$($GETOPT -o "n:v" -- "$@") if [ $? != 0 ]; then echo "Usage: $0 [-n MAX] [-v] query server..." > /dev/stderr exit 1 fi eval set -- "$TEMP" while true ; do case "$1" in -n) max=$2; shift 2;; -v) verbose=1; shift;; --) shift ; break ;; *) echo "Internal error!" > /dev/stderr ; exit 1 ;; esac done query=$1 shift servers="" for server in $*; do addresses=$(dig +short A $server ; dig +short AAAA $server) if [ -z "$addresses" ]; then # Let's hope it was an IP address addresses=$server fi for address in $addresses; do servers="$servers $server/$address" done done for i in 0 1 2; do for server in $servers; do address=$(echo $server | cut -d/ -f 2) # TODO: if the box has no IPv6 connectivity, or if it is an # old dig without IPv6, we get something like "dig: couldn't # get address for '2001:4f8:0:2::8': address family not # supported". Should we do something? echo "TEST: $server" dig @${address} ${query} done done | \ awk '/^TEST: / { server = $2; } \ /^;; Query time:/ { query_time = $4; } \ /^;; SERVER: / { sum[server] += query_time; num[server]++; } \ END { for (ns in sum) { print int(sum[ns]/num[ns]), ns; } }' | \ sort -n | head -${max}