#!/bin/sh
# Pen proxy wrapper, periodic check for best connections 
# Stichting Wireless Leiden
# Rick van der Zwet <rick@wirelessleiden.nl>

BIND_ADDR=${1-172.31.255.1}
BIND_PORT=${2-3128}
DEBUG=0

#XXX: Really static list, some dynamic alternative prefered
PROXY_LIST="${3-172.17.8.68:3128   \
                172.17.143.4:3128  \
		172.20.128.98:3128 \
		172.16.2.254:3128  \
		172.19.168.66:3128 \
		172.16.3.146:3128  \
                172.17.16.66:3128  \
		172.17.0.1:3128    \
		172.16.4.54:3128   \
                172.22.0.66:3128   \
                172.23.25.66:3128  \
                172.17.169.66:3128}"


TEST_URL="http://www.ams-ix.net/"
TEST_INTERVAL=`expr 30 \* 60` # Back-off period in seconds, re-testing period


# Don't touch, unless you know what you are doing
PIDFILE='/var/run/pen.pid'
PEN='/usr/local/bin/pen'
PEN_FLAGS="-b 30 -r -p ${PIDFILE} -o prio ${BIND_ADDR}:${BIND_PORT}"

LOGFILE='/var/log/pen_wrapper.log'

log()
{
	_datestamp=`date "+%Y-%m-%d %H:%M:%S"`
	_msg="[${_datestamp}] $*"
	if [ ${DEBUG} -eq 0 ]; then
		echo "${_msg}" >> ${LOGFILE}
	else
		echo "${_msg}"
	fi
}

d_log() {
	if [ ${DEBUG} -ne 0 ]; then
		log $*
	fi
}

test_proxy()
{
	# Set proxy
	PROXY=$1
	PORT=$2
	URL=$3
	export HTTP_PROXY="${PROXY}:${PORT}"

	# Attempted fetch
	retstr=`fetch -T 3 -o /dev/null ${URL} 2>&1`
	retval=$?

        # Store to list if successfull
	if [ "${retval}" -eq  0 ]; then
		BPS=`echo "${retstr}" | awk '/Bps/ {printf $4}'`
		echo "${BPS} ${PROXY}" >> ${TMPFILE}
	fi
	return $retval
}

sort_proxies()
{
	# Result holder
	TMPFILE=`mktemp -t pen_wrapper`

	for _host in ${PROXY_LIST}; do
		PROXY=`echo $_host | cut -d ":" -f1`
		PORT=`echo $_host | cut -d ":" -f2`
		_msg="Fetching '${TEST_URL}' via '${PROXY}:${PORT}' ..."
		test_proxy ${PROXY} ${PORT} ${TEST_URL} && d_log ${_msg} "OK" || d_log ${_msg} "FAILED"
	done

	_proxylist=`sort -nr ${TMPFILE} | awk '{print $2}' | tr '\n' ' '`
	_cfg="0:0:1:1"
	if [ -n "${_proxylist}" ]; then
		_prio="0"
		_proxy_arg=""
		for _proxy in ${_proxylist}; do
			_prio=`expr ${_prio} + 1`
			_proxy_arg="${_proxy_arg} ${_proxy}:${PORT}:${_cfg}:${_prio}"
		done
	fi
	# Clear out junk
	rm -f ${TMPFILE}
	NEW_PROXY_LIST="${_proxy_arg}"
}


##
# Main loop
LIVE_PROXY_LIST=''
while true; do
	sort_proxies
	if [ "${LIVE_PROXY_LIST}" != "${NEW_PROXY_LIST}" ]; then
		log "INFO: New listing to be configured '${NEW_PROXY_LIST}'"
		d_log "Live: ${LIVE_PROXY_LIST}"
		d_log "New : ${NEW_PROXY_LIST}"
		# Pen should only be started if alias exists
		ifconfig | grep -q ${BIND_ADDR}
		if [ $? -eq 0 ]; then
			if [ -r ${PIDFILE} ]; then
				kill `cat ${PIDFILE}`
			fi
			${PEN} ${PEN_FLAGS} ${NEW_PROXY_LIST}
			LIVE_PROXY_LIST="${NEW_PROXY_LIST}"
		fi
	fi
	sleep ${TEST_INTERVAL}
done
