#!/bin/sh
# some ideas came from validation script of bind9
# https://sources.debian.org/src/bind9/1:9.17.19-3/debian/tests/validation

# not used `set -e' because dig can fail

# DNSA = authoritative DNS server
# DNSR = recursive DNS server

STATUS_ERROR=1
STATUS_SKIP=77

PORT_DNSA=53001
PORT_DNSR=53002
PORT_DNSPROXY=53000

setup() {
    stop_dnsproxy
    service named stop

    start_dnsa
    start_dnsr
    start_dnsproxy
}

start_dnsa() {
    named -u bind -p $PORT_DNSA -f &
    pid_dnsa="$!"
}

start_dnsr() {
    named -u bind -p $PORT_DNSR -f &
    pid_dnsr="$!"
}

# $1 = pid of dnsa/dnsr
stop_dnsi() {
    kill -9 $1
}

start_dnsproxy() {
    service dnsproxy start
}

stop_dnsproxy() {
    service dnsproxy stop
}

# remove 127.0.0.1 from allowed recursive queries
dnsproxy_conf_update() {
    srcconf="/etc/dnsproxy.conf"
    newconf="$AUTOPKGTEST_TMP/dnsproxy.conf"

    # not used `sed' due lack of compatibility in multiple systems
    head -n -1 $srcconf > $newconf
    mv $newconf $srcconf
}

# $1 port to query
# $2 status to return on error
run_dig() {
    port=$1
    status=$2

    MAXTRY=5
    itry=0
    while [ $itry -lt $MAXTRY ]; do
        dig -x 127.0.0.1 @127.0.0.1 -p $port | grep -o \
                                          'status: NOERROR' 2>/dev/null && break
        itry=`expr $itry + 1`

        sleep 1
    done

    if [ "$itry" -eq "$MAXTRY" ]; then
        echo "dig query on port $port failed $MAXTRY times"
        echo "ending $0 with status $status"
        exit $status
    fi
}

pretests() {
    echo "PRETEST1: bind running with PID $pid_dnsa"
    ps -p $pid_dnsa || exit $STATUS_SKIP

    echo "PRETEST2: bind running with PID $pid_dnsr"
    ps -p $pid_dnsr || exit $STATUS_SKIP

    echo "PRETEST3: query bind on port $PORT_DNSA"
    run_dig $PORT_DNSA $STATUS_SKIP

    echo "PRETEST4: query bind on port $PORT_DNSR"
    run_dig $PORT_DNSR $STATUS_SKIP
}

test1() {
    echo "TEST1: dnsproxy with authoritative and recursive servers DNS servers"

    run_dig $PORT_DNSPROXY $STATUS_ERROR
}

test2() {
    echo "TEST2: dnsproxy with only a recursive server [UDP PORT=$PORT_DNSR]"

    stop_dnsproxy
    stop_dnsi $pid_dnsa
    start_dnsproxy

    run_dig $PORT_DNSPROXY $STATUS_ERROR
}

test3() {
    echo "TEST3: dnsproxy with only an authoritative server [UDP PORT=$PORT_DNSA]"

    stop_dnsproxy
    stop_dnsi $pid_dnsr
    start_dnsa
    dnsproxy_conf_update
    start_dnsproxy

    run_dig $PORT_DNSPROXY $STATUS_ERROR
}

stop_at_end() {
    stop_dnsi $pid_dnsa
    stop_dnsproxy
}

## main
setup
pretests
test1
test2
test3
stop_at_end

exit 0
