#!/bin/sh /etc/rc.common

START=60

extra_command "makeconfig"
extra_command "makegfwlist"
extra_command "health"

CRON_FILE=/etc/crontabs/root
PID_PATH=/var/run/dnsforwarder
PID_FILE=${PID_PATH}/dns.pid
DNSFORWARDER_CONF=/tmp/dnsforwarder.conf

add_cron()
{
	sed -i '/dnsforwarder/d' $CRON_FILE
	echo '*/5 * * * * /etc/init.d/dnsforwarder health' >> $CRON_FILE
	echo '0 1 * * 0 /etc/init.d/dnsforwarder makegfwlist' >> $CRON_FILE
	crontab $CRON_FILE
}

del_cron()
{
	sed -i '/dnsforwarder/d' $CRON_FILE
	/etc/init.d/cron restart
}

fixflowoffload(){
    dns=$(uci get flowoffload.@flow[0].dns 2>/dev/null)
    if [ $dns -eq 1 ];  then
        uci set flowoffload.@flow[0].dns=0 && uci commit flowoffload
        /etc/init.d/flowoffload restart
    fi
}

makelist() {
    [ -z "$2" ] && return
    local i
    local t="$1"; shift
    for i in "$@"
    do
        echo "$t $i"
    done
}

health(){
	rm /var/log/dnsforwarder.log.* 2>/dev/null
	local pid=$(cat ${PID_FILE} 2>/dev/null)
	if [ -n "${pid}" -a -d /proc/$pid ]; then
		echo "[health] process exists ${pid}"
	else
		echo "[health] Dnsforwarder is not running ${pid}"
		start
	fi
}


makegfwlist(){
	local GFW_FILE='/etc/dnsforwarder/gfw.txt'
	local GFW_TMP_FILE='/tmp/dnsforwarder-gfw.old'
	local TSTIME=`date '+%Y-%m-%d %H:%M:%S'`
	touch ${GFW_TMP_FILE}
	cat /etc/config/gfw.list 2>/dev/null > /tmp/edf.ts
	cat /etc/dnsmasq.ssr/gfw_base.conf 2>/dev/null | awk -F '/' '{print $2}' | sed 's/^.//g' >> /tmp/edf.ts
	cat /etc/dnsmasq.ssr/gfw_list.conf 2>/dev/null | awk -F '/' '{print $2}' | sed 's/^.//g' >> /tmp/edf.ts
	sort /tmp/edf.ts  | uniq > /tmp/edf.ts
	/usr/share/dnsforwarder/gfwlist.sh -i -l -o /tmp/dnsforwarder-gfw.tmp --extra-domain-file /tmp/edf.ts
	if [ $? != 0 ]; then
        echo 'Failed to fetch gfwlist'
		logger -t  Failed to fetch gfwlist
        return 2
    fi
	local gfw=$(cat /tmp/dnsforwarder-gfw.tmp)
	echo "# GenerationAt TS_BUILD_TIME" > ${GFW_TMP_FILE}.new
	echo "protocol tcp" >> ${GFW_TMP_FILE}.new
	echo "server 8.8.8.8,8.8.4.4,1.1.1.1,1.0.0.1,208.67.222.222,208.67.220.220,209.244.0.3,209.244.0.4,8.26.56.26,8.20.247.20,156.154.70.1,156.154.71.1,199.85.126.10" >> ${GFW_TMP_FILE}.new
	echo -e 'proxy no\n\n\n' >> ${GFW_TMP_FILE}.new
	echo "${gfw}" >> ${GFW_TMP_FILE}.new
	if [ "`cat ${GFW_TMP_FILE}.new | md5sum`" == "`cat ${GFW_TMP_FILE} | md5sum`" ]; then
		printf "[\e[32m%s\e[0m]\n" "hold"
	else
		cp ${GFW_TMP_FILE}.new ${GFW_TMP_FILE}
		cp ${GFW_TMP_FILE} ${GFW_FILE}
		sed -i "s/TS_BUILD_TIME/${TSTIME}/g" ${GFW_FILE}
		printf "[\e[33m%s\e[0m]" "PID"
		restart
	fi
}

makeconfig () {
    config_load dnsforwarder

    local log=$(uci get dnsforwarder.@config[0].log 2>/dev/null)
    local log_size=$(uci get dnsforwarder.@config[0].log_size 2>/dev/null)

	local gfw=$(uci get dnsforwarder.@config[0].gfw 2>/dev/null)

	local udp_local=$(uci -d ',' get dnsforwarder.@config[0].udp_local 2>/dev/null)
	local udp_local_list=$(uci get dnsforwarder.@config[0].udp_local 2>/dev/null)
	local tcp_group=$(uci get dnsforwarder.@config[0].tcp_group 2>/dev/null)
	local udp_group=$(uci get dnsforwarder.@config[0].udp_group 2>/dev/null)
	local group_file=$(uci get dnsforwarder.@config[0].group_file 2>/dev/null)
	local block_ip=$(uci -d ',' get dnsforwarder.@config[0].block_ip 2>/dev/null)
	local ip_substituting=$(uci -d ',' get dnsforwarder.@config[0].ip_substituting 2>/dev/null)
	local block_negative_resp=$(uci get dnsforwarder.@config[0].block_negative_resp 2>/dev/null)
	local append_host=$(uci get dnsforwarder.@config[0].append_host 2>/dev/null)
	local block_ipv6=$(uci get dnsforwarder.@config[0].block_ipv6 2>/dev/null)

	local cache=$(uci get dnsforwarder.@config[0].cache 2>/dev/null)
	local cache_size=$(uci get dnsforwarder.@config[0].cache_size 2>/dev/null)
	local cache_ignore=$(uci get dnsforwarder.@config[0].cache_ignore 2>/dev/null)
	local cache_control=$(uci get dnsforwarder.@config[0].cache_control 2>/dev/null)

	local domain_statistic=$(uci get dnsforwarder.@config[0].domain_statistic 2>/dev/null)
	local udp_local_addr=$(uci get dnsforwarder.@arguments[0].addr 2>/dev/null)
	udp_local_addr=${udp_local_addr/:/#}

    echo "LogOn ${log}" > $DNSFORWARDER_CONF
    if [ $log = "true" ]; then
		rm /var/log/dnsforwarder.log.* 2>/dev/null
		echo '' > /var/log/dnsforwarder.log
        echo "LogFileThresholdLength ${log_size}" >> $DNSFORWARDER_CONF
        echo "LogFileFolder /var/log" >> $DNSFORWARDER_CONF
    fi

    [ -n "$udp_local" ] && echo "UDPLocal ${udp_local}" >> $DNSFORWARDER_CONF
	[ -n "$udp_local_addr" ] && eval "makelist 'server=' $udp_local_addr" > /tmp/dnsmasq.dnsforwarder.conf
	sed -i "s/ //g" /tmp/dnsmasq.dnsforwarder.conf

    eval "makelist 'TCPGroup' $tcp_group" >> $DNSFORWARDER_CONF
    eval "makelist 'UDPGroup' $udp_group" >> $DNSFORWARDER_CONF
    eval "makelist 'GroupFile' $group_file" >> $DNSFORWARDER_CONF

	if [ $gfw = "true" ]; then
        echo 'GroupFile /etc/dnsforwarder/gfw.txt' >> $DNSFORWARDER_CONF
    fi

    echo "BlockIP  ${block_ip}" >> $DNSFORWARDER_CONF
    eval "makelist 'IPSubstituting' $ip_substituting" >> $DNSFORWARDER_CONF
    echo "BlockNegativeResponse ${block_negative_resp}" >> $DNSFORWARDER_CONF
    eval "makelist 'AppendHosts' $append_host" >> $DNSFORWARDER_CONF
    echo "BlockIpv6WhenIpv4Exists ${block_ipv6}" >> $DNSFORWARDER_CONF

    echo "UseCache ${cache}" >> $DNSFORWARDER_CONF
    if [ $cache = "true" ]; then
        echo "CacheSize ${cache_size}" >> $DNSFORWARDER_CONF
        echo "MemoryCache false" >> $DNSFORWARDER_CONF
        echo "CacheFile /tmp/dnsforwarder.cache" >> $DNSFORWARDER_CONF
        echo "IgnoreTTL ${cache_ignore}" >> $DNSFORWARDER_CONF
        eval "makelist 'CacheControl' $cache_control" >> $DNSFORWARDER_CONF
        echo "ReloadCache true" >> $DNSFORWARDER_CONF
        echo "OverwriteCache true" >> $DNSFORWARDER_CONF
    fi
	echo "DomainStatistic ${domain_statistic}" >> $DNSFORWARDER_CONF
	if [ $domain_statistic = "true" ]; then
		touch /tmp/dnsforwarder-statistic.html
		mkdir -p /root/.dnsforwarder
		rm /root/.dnsforwarder/statistic.html 2 > /dev/null
		ln -s /tmp/dnsforwarder-statistic.html /root/.dnsforwarder/statistic.html
		local domain_statistic_tag='<!-- TS DNSFORWARDER -->'
		echo "DomainStatisticTempletFile /tmp/dnsforwarder-statistic.html" >> $DNSFORWARDER_CONF
		echo "StatisticInsertionPosition ${domain_statistic_tag}" >> $DNSFORWARDER_CONF
		echo "StatisticUpdateInterval 60" >> $DNSFORWARDER_CONF
		echo "${domain_statistic_tag}"  > /tmp/dnsforwarder-statistic.html
    fi
}

start()
{
    echo luci for dnsforwarder
    local vt_enabled=$(uci get dnsforwarder.@arguments[0].enabled 2>/dev/null)
    if [ $vt_enabled = 0 ]; then
        echo dnsforwarder is not enabled
        exit
    fi
    makeconfig
	fixflowoffload	
    dnsforwarder -f $DNSFORWARDER_CONF -d
	sleep 10
    mkdir -p ${PID_PATH}
    pid=$(ps | awk '$5 ~ /\[dnsforwarder\]/ {print $1}')
    echo "dnsforwarder running pid is ${pid}"
    logger -t The pid of dnsforwarder is ${PID_FILE} ${pid}
    echo ${pid} > ${PID_FILE}
    /etc/init.d/dnsforwarder enable
    local dnsmasq=$(uci get dnsforwarder.@arguments[0].dnsmasq 2>/dev/null)
    local addr=$(uci get dnsforwarder.@arguments[0].addr 2>/dev/null)
    [ -n "${addr}" ] && addr=${addr/:/#}

	if [ "${dnsmasq}" = "1" ]; then
        uci delete dhcp.@dnsmasq[0].server 2>/dev/null
        # uci add_list dhcp.@dnsmasq[0].server=$addr
        uci delete dhcp.@dnsmasq[0].resolvfile 2>/dev/null
        uci set dhcp.@dnsmasq[0].noresolv=1
		uci set dhcp.@dnsmasq[0].serversfile=/tmp/dnsmasq.dnsforwarder.conf
        uci commit dhcp
        /etc/init.d/dnsmasq restart
    fi
    	local dnsmasq_server_addr=$(uci get dhcp.@dnsmasq[0].server 2>/dev/null)
	if [ -n "${dnsmasq_server_addr}" ]; then
		uci set dhcp.@dnsmasq[0].noresolv=1
		uci commit dhcp 
		/etc/init.d/dnsmasq restart
	fi
	add_cron
}

stop()
{
	del_cron
	logger -t stopping dnsforwarder
    local addr=$(uci get dnsforwarder.@arguments[0].addr 2>/dev/null)
    local dnsmasq=$(uci get dnsforwarder.@arguments[0].dnsmasq 2>/dev/null)
    addr=${addr/:/#}
    if [ "${dnsmasq}" = "1" ]; then
	    uci del_list dhcp.@dnsmasq[0].server=$addr 2>/dev/null
    fi
    uci set dhcp.@dnsmasq[0].resolvfile=/tmp/resolv.conf.d/resolv.conf.auto 2>/dev/null
    uci delete dhcp.@dnsmasq[0].noresolv 2>/dev/null
	uci delete dhcp.@dnsmasq[0].serversfile 2>/dev/null
    uci commit dhcp
    /etc/init.d/dnsmasq restart
    [ -e ${PID_FILE} ] && {
        pid=$(cat ${PID_FILE})
        logger -t killing dnsforwarder pid ${pid}
        echo killing dnsforwarder pid ${pid}
        kill ${pid}
        rm -f ${PID_FILE}
    } || {
        logger -t Cannot find dnsforwarder pid file
    }
}

restart()
{
    pid=$(cat ${PID_FILE} 2>/dev/null)
    echo Dnsforwarder pid file is ${pid}
    [ -n "$pid" ] && {
        echo stopping pid ${pid}
        logger -t There is dnsforwarder pid ${pid}
        stop
    } || {
        logger -t Dnsforwarder is not running
    }
    sleep 7
    local vt_enabled=$(uci get dnsforwarder.@arguments[0].enabled 2>/dev/null)
    echo dnsforwarder status is ${vt_enabled}
    logger -t Dnsforwarder is initializing enabled is ${vt_enabled}
    if [ ${vt_enabled} = 1 ]; then
        [ -n "$pid" ] && {
            logger -t There is dnsforwarder pid ${pid}
            stop
        } || {
            logger -t Dnsforwarder is not running
        }

        logger -t Restarting dnsforwarder
        start
    else
        /etc/init.d/dnsforwarder disable
    fi
}
