#!/bin/sh 

. /lib/functions.sh
. /lib/functions/network.sh

PIDPATH=/var/run
tunnel_id=0

tunnel_is_up() {
        local iface=$1
        local pidfile="${PIDPATH}/tunneldigger.${iface}.pid"
        local pid=0
        local result=0

        [ -e ${pidfile} ] && pid="$(cat ${pidfile})"
        [ ${pid} != 0 ] && [ -d "/proc/${pid}" ] && result=1
        echo "${result}"
}

interface_disabled() {
        local iface=$1
        local disabled
        disabled="$(uci -q get network.${iface}.disabled)"
        [ -z $disabled ] && disabled=0
        echo "${disabled}"
}

srv_lookup() {
        local srv="$1"
        local i
        local srvlist=""
        for i in $srv; do
                local lookup
                lookup="$(nslookup -q=SRV $i | grep $i | cut -d "=" -f 2)"
                local OLDIFS=$IFS
                IFS=$'\n'
                local j
                for j in $lookup; do
                        local host
                        local port
                        host="$(echo $j | cut -d ' ' -f 5)"
                        port="$(echo $j | cut -d ' ' -f 4)"
                        append srvlist "${host}:${port}"
                done
                IFS=$OLDIFS
        done

        echo "${srvlist}"
}

missing() {
        logger -t td-client "Not starting tunneldigger \"$1\" - missing $2" >&2
}

handle_td_ifup() {
        local cfg=$1
        local enabled
        local srv
        local addresses
        local uuid
        local interface
        local group
        local limit_bw_down
        local hook_script
        local bind_interface
        local broker_selection

        config_get_bool enabled "$cfg" enabled 1
        config_get srv "$cfg" srv
        config_get addresses "$cfg" address
        config_get uuid "$cfg" uuid
        config_get interface "$cfg" interface
        config_get group "$cfg" group
        config_get limit_bw_down "$cfg" limit_bw_down
        config_get hook_script "$cfg" hook_script
        config_get bind_interface "$cfg" bind_interface
        config_get broker_selection "$cfg" broker_selection

        let tunnel_id++

        [ $enabled -eq 0 ] && return
        [ ! -z ${bind_interface} ] && \
                [ "$INTERFACE" != "${bind_interface}" ] && \
                [ "$INTERFACE" != "${interface}" ] && return
        [ "$(interface_disabled ${interface})" == "1" ] && \
                logger -t td-client "Not starting tunneldiger \"${cfg}\", interface ${interface} disabled" && return
        [ "$(tunnel_is_up ${interface})" == "1" ] && return

        local broker_opts=""

        # use addresses provided by srv before the addresses list
        # in most circumstances, only an srv entry should be found
        # or a list of addresses.  Here, we handle both.
        srvlist=$(srv_lookup "$srv")
        local address
        local count=0
        for address in $srvlist $addresses; do
                count=$(($count+1))
                [ $count -gt 10 ] && break # limit of 10 addresses
                append broker_opts "-b ${address}"
        done

        [ ! -z "${limit_bw_down}" ] && append broker_opts "-L ${limit_bw_down}"
        [ ! -z "${hook_script}" ] && append broker_opts "-s ${hook_script}"
        [ ! -z "${bind_interface}" ] && {
                # Resolve logical interface name.
                unset _bind_interface
                network_get_device _bind_interface "${bind_interface}" || _bind_interface="${bind_interface}"
                append broker_opts "-I ${_bind_interface}"
        }
        [ ! -z "${broker_selection}" ] && {
                # Set broker selection.
                case "${broker_selection}" in
                        usage)
                                append broker_opts "-a"
                        ;;
                        first)
                                append broker_opts "-g"
                        ;;
                        random)
                                append broker_opts "-r"
                        ;;
                esac
        }

        if [ -z "$uuid" ]; then
                missing $cfg uuid
                return
        elif [ -z "$interface" ]; then
                missing $cfg interface
                return
        fi

        logger -t td-client "Starting tunneldigger \"$cfg\" on ${interface}"
        /sbin/start-stop-daemon -S -q -b -m -c root:${group} -p ${PIDPATH}/tunneldigger.${interface}.pid -x /usr/bin/tunneldigger -- -u ${uuid} -i ${interface} -t ${tunnel_id} ${broker_opts}
}

handle_td_ifdown() {
        local cfg=$1
        local interface
        local bind_interface

        config_get interface "$cfg" interface
        config_get bind_interface "$cfg" bind_interface

        [ -z ${bind_interface} ] && [ "$INTERFACE" != "$interface" ] && \
                return

        [ ! -z  ${bind_interface} ] && [ "$INTERFACE" != "${bind_interface}" ] && \
                return

        [ "$(tunnel_is_up ${interface})" != "1" ] && return

        local PIDFILE=${PIDPATH}/tunneldigger.${interface}.pid
        local PID
        PID="$(cat ${PIDFILE})"
        logger -t td-client "Stopping tunneldigger \"$cfg\" on ${interface} PIDFILE=${PIDFILE}"
        /sbin/start-stop-daemon -K -q -p $PIDFILE 
        while test -d "/proc/${PID}"; do 
                logger -t td-client "  waiting for tunneldigger to stop" 
                sleep 1 
        done
        rm -f "${PIDFILE}"
        logger -t td-client "  tunneldigger stopped" 
}

config_load tunneldigger
if [ "$ACTION" = ifup ]; then
        config_foreach handle_td_ifup broker
fi

if [ "$ACTION" = ifdown ]; then
        config_foreach handle_td_ifdown broker
fi


