#!/bin/bash

# ssh-tunnels 1.0 - mail AT patrick-nagel DOT net

declare -a LOCALPORT
declare -a REMOTEPORT
declare -a HOST
declare -a SSHPID

### Configuration starts here

CHECKINTERVAL=15     # Check tunnels every 15 seconds

# Tunnel 1
# irssi proxy for bitlbee
LOCALPORT[0]=16666
REMOTEPORT[0]=6666
HOST[0]=james

# Tunnel 2
# irssi proxy for freenode
LOCALPORT[1]=16665
REMOTEPORT[1]=6665
HOST[1]=james

# Tunnel 3
# tinyproxy
LOCALPORT[2]=13128
REMOTEPORT[2]=3128
HOST[2]=james

# Tunnel 4
# privoxy
LOCALPORT[3]=13129
REMOTEPORT[3]=3129
HOST[3]=james

# Tunnel 5
# ldap
LOCALPORT[4]=1389
REMOTEPORT[4]=389
HOST[4]=james

COUNT=5

### Configuration ends here



function establish_tunnels() {

	echo -n "Establishing $COUNT tunnels... "
	for (( i=0; i < $COUNT; i++ )); do
	{
		ssh -fNL ${LOCALPORT[$i]}:localhost:${REMOTEPORT[$i]} ${HOST[$i]}
		SSHPID[$i]="$(pgrep -f "ssh -fNL ${LOCALPORT[$i]}:localhost:${REMOTEPORT[$i]} ${HOST[$i]}")"
		echo -n "${SSHPID[$i]} "
	}
	done
	echo "done."

	FAILURE="0"
}


# MAIN


# Check if tunnels already exist, otherwise establish them.

echo "Checking for already established tunnels:"
echo -n "Found... "
for (( i=0; i < $COUNT; i++ )); do
{
	SSHPID[$i]="$(pgrep -f "ssh -fNL ${LOCALPORT[$i]}:localhost:${REMOTEPORT[$i]} ${HOST[$i]}")" && FOUND="1" || FAILURE="1"
	echo -n "${SSHPID[$i]} "
}
done

if [[ "$FOUND" == "1" ]]; then
{
	echo "done."
}
else
{
	echo "none."
}
fi

if [[ "$FAILURE" == "1" ]]; then
{
	echo "At least one tunnel hasn't been already established."
	echo "Killing all and establishing new tunnels."
	pkill -f "ssh -fNL.*"
	establish_tunnels
}
fi

# Check periodically if the ssh sessions are still alive. If not,
# re-establish the tunnels.

while ((1)); do
{
	PIDLIST="$(ps -U $USER -o pid | tr '\n' ' ')"

	echo -n "Checking... "
	for i in "${SSHPID[@]}"; do
	{
		if [[ "$i" == "" ]]; then
		{
			echo "No PID - something went wrong."
			FAILURE="1"
			break
		}
		fi

		echo -n "$i "

		echo "$PIDLIST" | grep "$i" >/dev/null || { FAILURE="1"; break; }
	}
	done
	echo "done."

	if [[ "$FAILURE" == "1" ]]; then
	{
		echo "Error: At least one tunnel is broken."
		# Kill eventually remaining processes
		echo -n "Trying to kill... "
		for i in "${SSHPID[@]}"; do
		{
			echo -n "$i "
			kill "$i" &>/dev/null
		}
		done
		echo "done."

		sleep 1

		establish_tunnels
	}
	fi

	sleep $CHECKINTERVAL
}
done
