#!/bin/sh
. /lib/functions/network.sh
echo "nameserver 114.114.114.114" > /etc/resolv.conf
echo "nameserver 180.76.76.76" > /etc/resolv.conf
_checkpid(){
	pid=`echo $$`
	pname=`echo $0`
	mypidfile=/tmp/myvpn.pid
	if test -f "$mypidfile";then
		expid=`cat $mypidfile`
		if grep $pname /proc/`cat $mypidfile`/cmdline > /dev/null 2>&1 ;then
			echo "The process $pname is already exists ! pid:$expid."
			exit 0
		fi		
	fi
	echo $pid > $mypidfile
}

_getinfo(){
	echo "127.0.0.1 localhost">/etc/hosts
	touch /etc/config/myvpn
	uci get  myvpn.@myvpn[0] > /dev/null 2>&1
	if [ "$?" != "0" ];then
		 uci add myvpn myvpn
		 uci add_list myvpn.@myvpn[0].subnets="192.168.0.0/16"
		 uci add_list myvpn.@myvpn[0].subnets="100.64.0.0/12"
		 uci add_list myvpn.@myvpn[0].subnets="172.16.0.0/10"
		 uci add_list myvpn.@myvpn[0].subnets="10.0.0.0/8"
		 uci commit myvpn
	fi
	network_find_wan NET_IF
	network_get_ipaddr NET_IP "${NET_IF}"
	network_get_dnsserver NET_DNS "${NET_IF}"
	if [ "$NET_DNS" = "" ];then
		NET_DNS=180.76.76.76
	fi
	echo "server=180.76.76.76" > /etc/dnsmasq.conf
	/etc/init.d/dnsmasq restart > /dev/null 2>&1
	network_get_gateway NET_GATEWAY "${NET_IF}"
	if opkg list-installed|grep quagga > /dev/null 2>&1;then
		quagga=1
	else
		quagga=0
	fi
	if dnsmasq --help|grep chnroute > /dev/null 2>&1;then
		dnsmasq=1
	else
		dnsmasq=0
	fi
}

_checkdnsmasq(){
	network_find_wan NET_IF
	network_get_ipaddr NET_IP "${NET_IF}"
	network_get_dnsserver NET_DNS "${NET_IF}"
	if [ "$NET_DNS" = "" ];then
		NET_DNS=180.76.76.76
	fi
	if [ "$dnsmasq" = "1" ];then
cat>/tmp/dnsmasq.tmp<<EOF
no-resolv
all-servers
server=180.76.76.76,0
server=1.1.1.1,1
chnroutes-file=/etc/chnroute

EOF
		dnsconfmd5=`md5sum /tmp/dnsmasq.tmp|awk '{print $1}'`
		dnsmasqmd5=`md5sum /etc/dnsmasq.conf|awk '{print $1}'`
		if [ "$dnsconfmd5" != "$dnsmasqmd5" ];then
			cp /tmp/dnsmasq.tmp /etc/dnsmasq.conf
			/etc/init.d/dnsmasq restart > /dev/null 2>&1
		fi
	else
		dnsconf=`wc -l /etc/dnsmasq.conf|awk '{print $1}'`
		if [ "$dnsconf" -gt "1" ];then
			echo "server=114.114.114.114" > /etc/dnsmasq.conf
			/etc/init.d/dnsmasq restart > /dev/null 2>&1
		fi
	fi
	
}

_checkroute(){
	if [ "$quagga" = "1" ];then
		if [ "$vpnside" = "2" ];then
			routenum=`ip route|grep tochina|wc -l`
			if [ "$routenum" -lt "5000" ];then
				sed 's/^/ip route &/g' /etc/chnroute > /etc/quagga/zebra.conf
				sed -i 's/$/& vpn-tochina/g' /etc/quagga/zebra.conf
				/etc/init.d/quagga restart > /dev/null 2>&1
				if [ "$?" != "0" ];then
					quagga=0
				fi
				/etc/init.d/dnsmasq restart > /dev/null 2>&1
			fi
		else
			routenum=`ip route|grep toglobal|wc -l`
			if [ "$routenum" -lt "11300" ];then
				sed 's/^/ip route &/g' /etc/toglobal > /etc/quagga/zebra.conf
				sed -i 's/$/& vpn-toglobal/g' /etc/quagga/zebra.conf
				/etc/init.d/quagga restart > /dev/null 2>&1
				if [ "$?" != "0" ];then
					quagga=0
				fi
				/etc/init.d/dnsmasq restart > /dev/null 2>&1
			fi
		fi
	else
		if [ "$vpnside" = "2" ];then
			routenum=`ip route|grep tochina|wc -l`
			if [ "$routenum" -lt "5000" ];then
				for ip in `cat /etc/chnroute`;do
					ip route add $ip dev vpn-tochina
				done
				/etc/init.d/dnsmasq restart > /dev/null 2>&1
			fi
		else
			routenum=`ip route|grep $NET_GATEWAY|wc -l`
			if [ "$routenum" -lt "5000" ];then
				for ip in `cat /etc/chnroute`;do
					echo ip route add $ip via $NET_GATEWAY
				done
				ip route 0.0.0.0/1 dev vpn-toglobal
				ip route 128.0.0.0/1 vpn-toglobal
				/etc/init.d/dnsmasq restart > /dev/null 2>&1
			fi
		fi
	fi
	_checkdnsmasq
}

check_ip() {
    local IP=$1
    VALID_CHECK=$(echo $IP|awk -F. '$1<=255&&$2<=255&&$3<=255&&$4<=255{print "yes"}')
    if echo $IP|grep -E "^[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}$" >/dev/null; then
        if [ "$VALID_CHECK" = "yes" ]; then
            return 0
        else
            return 1
        fi
    else
        return 1
    fi
}

_get_dn_ip(){
	. /usr/share/libubox/jshn.sh
	domain=$1
	server_ip=$(resolveip $domain)
	check_ip() $server_ip
	if [ "$?" = "0" ];then
		echo $server_ip
	else
		dns_info=$(curl -L -s -k --connect-timeout 5 -H 'accept: application/dns-json' 'https://120.53.53.53/dns-query?name='$domain'&type=A')
		json_load "$dns_info"
		json_get_var Status Status
		if [ "$Status" = "0" ];then
			json_select Answer
			json_get_keys keys
				for k in $keys; do
					json_select $k
					json_get_var name name
					json_get_var data data
					json_select ..
				done
				json_select ..
			echo $data
		fi
	fi
}

_connectvpn(){
	ip link del vpn-toglobal
	ip link del vpn-$vpname
	apiserver=`uci get myvpn.@myvpn[0].server|sed s/[[:space:]]//g`
	vpnserver=`curl -s -A OpenConnect https://$apiserver/openwrt/`
	vpnport=`echo $vpnserver|awk -F ":" '{print $2}'`
	vpnserver=`echo $vpnserver|awk -F ":" '{print $1}'`
	vpnusername=`uci get myvpn.@myvpn[0].username|sed s/[[:space:]]//g`
	vpnpassword=`uci get myvpn.@myvpn[0].password|sed s/[[:space:]]//g`

	uci set network.$vpname=interface
	uci set network.$vpname.proto='openconnect'
	uci set network.$vpname.auto='0'
	uci set network.$vpname.delegate='0'
	uci set network.$vpname.defaultroute='0'
	uci set network.$vpname.port=$vpnport
	uci set network.$vpname.username=$vpnusername
	uci set network.$vpname.password=$vpnpassword
	uci set network.$vpname.server=$vpnserver
	uci commit network.$vpname
	FIREWALL=$(uci get firewall.@zone[1].network)
	echo $FIREWALL|grep $vpname >/dev/null
	if [ "$?" != "0" ];then
		echo " Add $vpname to Firewall"
		uci set firewall.@zone[1].network="$FIREWALL $vpname"
		uci commit firewall
	fi
	ifup $vpname
	_checkroute
}

_checkvpnconnect(){
	uci get myvpn.@myvpn[0].selectroute >/dev/null 2>&1
	if [ "$?" = "0" ];then
		vpnside=`uci get myvpn.@myvpn[0].selectroute`
	fi
	if [ "$vpnside" = "2" ];then
		vpname=tochina
		ifdown toglobal > /dev/null 2>&1
		ip link del dev vpn-toglobal > /dev/null 2>&1
	else
		vpname=toglobal
		uci set myvpn.@myvpn[0].selectroute=toglobal
		uci commit myvpn
		ifdown tochina > /dev/null 2>&1
		ip link del dev vpn-tochina > /dev/null 2>&1
	fi	
	if ifconfig vpn-$vpname >/dev/null 2>&1;then
		echo "_checkroute"
	else
		_connectvpn
	fi
}

_checkmyvpn(){
	if uci get myvpn.@myvpn[0].enable >/dev/null 2>&1;then
		_checkvpnconnect
	fi
}

_fixbrwifi(){
	cat /var/state/wireless >/dev/null 2>&1
	if [ "$?" = "0" ];then
		wifiuci=` cat /var/state/wireless | awk -F"." '{print $2}'`
		wififace=`uci get wireless.$wifiuci.ifname`
		brname=`brctl show|grep -v "bridge name"| awk '{print $1}'|grep -v $wififace `
		brctl show |grep $wififace > /dev/null 2>&1
		if [ "$?" != "0" ];then
			brctl addif $brname $wififace
		fi
	fi
}

_checkupdate(){
	onlinemd5=`curl -s -k --connect-timeout 3 https://$apiserver/downloads/ipk/md5|tail -1|awk '{print $1}'`
	if [ "${#onlinemd5}" = "32" ];then
		localmd5=`uci get myvpn.@myvpn[0].version`
		if [ "$onlinemd5" = "$localmd5" ];then
			return 0
		else
			return 1
		fi
	else
		return 0
	fi
}

_update(){
	uci get myvpn.@myvpn[0].update > /dev/null 2>&1
	if [ "$?" != "0" ];then
		/usr/sbin/myvpn upgrade > /dev/null
	else
		update=`uci get myvpn.@myvpn[0].update`
		if [ "$update" != "0" ];then
			/usr/sbin/myvpn upgrade > /dev/null
		fi
	fi
}
_upgrade(){
	_checkupdate
	if [ "$?" = "1" ];then
		onlinemd5=`curl -L -s -k --connect-timeout 3 https://$apiserver/downloads/ipk/md5|tail -1|awk '{print $1}'`
		onlineipk=`curl -L -s -k --connect-timeout 3 https://$apiserver/downloads/ipk/md5|tail -1|awk '{print $2}'`
		curl -L -s -k --connect-timeout 5 https://$apiserver/downloads/ipk/$onlineipk > /tmp/$onlineipk
		tmpmd5=`md5sum /tmp/$onlineipk|awk '{print $1}'`
		if [ "$onlinemd5" = "$tmpmd5" ];then
			opkg install /tmp/$onlineipk --force-depends
			if [ "$?" = "0" ];then
				uci set myvpn.@myvpn[0].version="$tmpmd5"
				uci commit myvpn
				return 0
			else
				return 1
			fi
		else
			return 1
		fi
	fi
}

_start(){
	_checkpid
	_getinfo
	while true;do
		_checkmyvpn
		_fixbrwifi
		_update
	sleep 10
	done
}

_stop(){
	ifdown tochina > /dev/null 2>&1
	ifdown toglobal > /dev/null 2>&1
	uci del network.toglobal > /dev/null 2>&1
	uci del network.tochina > /dev/null 2>&1
	uci commit network
	/etc/init.d/myvpn stop
}

action=$1
case "$action" in
stop) 
	_stop
	;;
checkupdate) 
	_checkupdate
	;;
upgrade) 
	_upgrade
	;;
*)
    _start
    ;;
esac

