|
|
|
@ -1,65 +1,73 @@
|
|
|
|
|
#!/bin/sh
|
|
|
|
|
|
|
|
|
|
# Usage: vpn-select <path-to-hood-file>
|
|
|
|
|
# To add a new protocol, put a file with three functions to /usr/lib/vpn-select.d/ .
|
|
|
|
|
# The file must start with protocol=name. It is most important to use the same name here and in hoodfile.
|
|
|
|
|
# Some parameters of the hood are available via $hood_id, $hood_name and $hood_protocol.
|
|
|
|
|
# The old config can be cleared in function ${protocol}_clear(). It is called first once per installed protocol.
|
|
|
|
|
# The function ${protocol}_addpeer() is called for every selected peer in hoodfile.
|
|
|
|
|
# The function ${protocol}_start_stop() is called at the end once per installed protocol.
|
|
|
|
|
#
|
|
|
|
|
# The variable $protocol_order defines the order of preference. The most preffered protocol of the available and offered protocols is selected.
|
|
|
|
|
# The $protocol_order is configurable via "uci fff.vpnselect.protocol_order"
|
|
|
|
|
# An empty protocol_order deactivates VPN.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
. /usr/share/libubox/jshn.sh
|
|
|
|
|
|
|
|
|
|
hoodfile="$1"
|
|
|
|
|
|
|
|
|
|
make_config() {
|
|
|
|
|
# remove old config
|
|
|
|
|
rm /tmp/fastd_fff_peers/*
|
|
|
|
|
# load protocol_order
|
|
|
|
|
protocol_order="$(uci get fff.vpnselect.protocol_order)"
|
|
|
|
|
|
|
|
|
|
# prepare
|
|
|
|
|
Index=1
|
|
|
|
|
# source functions
|
|
|
|
|
for file in /usr/lib/vpn-select.d/*; do
|
|
|
|
|
[ -f $file ] && . "$file"
|
|
|
|
|
supported_protocols="$supported_protocols $protocol"
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# compare $protocol_order with $supported_protocols
|
|
|
|
|
for proto in $protocol_order; do
|
|
|
|
|
echo "$supported_protocols" | grep -w $proto >&/dev/null || protocol_order=${protocol_order/$proto/}
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# clear old config
|
|
|
|
|
for protocol in $supported_protocols; do
|
|
|
|
|
"${protocol}_clear"
|
|
|
|
|
done
|
|
|
|
|
|
|
|
|
|
# configure vpn
|
|
|
|
|
|
|
|
|
|
if [ -n "$hoodfile" ] && [ -s "$hoodfile" ] ; then
|
|
|
|
|
json_load "$(cat "$hoodfile")"
|
|
|
|
|
# load hoodparameter
|
|
|
|
|
json_select hood
|
|
|
|
|
json_get_var hood_id id
|
|
|
|
|
json_get_var hood_name name
|
|
|
|
|
json_get_var hood_protocol protocol
|
|
|
|
|
json_select ".."
|
|
|
|
|
json_select vpn
|
|
|
|
|
|
|
|
|
|
# get fastd peers
|
|
|
|
|
while json_select "$Index" > /dev/null
|
|
|
|
|
do
|
|
|
|
|
json_get_keys vpn_keys
|
|
|
|
|
for k in $vpn_keys; do
|
|
|
|
|
json_select $k
|
|
|
|
|
json_get_var protocol protocol
|
|
|
|
|
if [ "$protocol" = "fastd" ]; then
|
|
|
|
|
# set up fastd
|
|
|
|
|
json_get_var servername name
|
|
|
|
|
filename="/etc/fastd/fff/peers/$servername"
|
|
|
|
|
echo "#name \"${servername}\";" > "$filename"
|
|
|
|
|
json_get_var key key
|
|
|
|
|
echo "key \"${key}\";" >> "$filename"
|
|
|
|
|
json_get_var address address
|
|
|
|
|
json_get_var port port
|
|
|
|
|
echo "remote \"${address}\" port ${port};" >> "$filename"
|
|
|
|
|
echo "" >> "$filename"
|
|
|
|
|
echo "float yes;" >> "$filename"
|
|
|
|
|
fi
|
|
|
|
|
offered_protocols="$offered_protocols $protocol"
|
|
|
|
|
json_select ".." # back to vpn
|
|
|
|
|
Index=$(( Index + 1 ))
|
|
|
|
|
done
|
|
|
|
|
json_select ".." # back to root
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
# Only do something if file is there and not empty; otherwise exit 1
|
|
|
|
|
if [ -s "$hoodfile" ]; then
|
|
|
|
|
if [ ! -d /tmp/fastd_fff_peers ]; then
|
|
|
|
|
# first run after reboot
|
|
|
|
|
mkdir /tmp/fastd_fff_peers
|
|
|
|
|
make_config
|
|
|
|
|
# start fastd only if there are some peers
|
|
|
|
|
[ "$(ls /etc/fastd/fff/peers/* 2>/dev/null)" ] && /etc/init.d/fastd start
|
|
|
|
|
else
|
|
|
|
|
make_config
|
|
|
|
|
/etc/init.d/fastd reload
|
|
|
|
|
# select most preferred protocol for this hood
|
|
|
|
|
selected_protocol=$(for proto in $protocol_order; do echo $offered_protocols | grep -o $proto && break; done)
|
|
|
|
|
|
|
|
|
|
# fastd start/stop for various situations
|
|
|
|
|
pidfile="/tmp/run/fastd.fff.pid"
|
|
|
|
|
if [ "$(ls /etc/fastd/fff/peers/* 2>/dev/null)" ]; then
|
|
|
|
|
([ -s "$pidfile" ] && [ -d "/proc/$(cat "$pidfile")" ]) || /etc/init.d/fastd start
|
|
|
|
|
else
|
|
|
|
|
([ -s "$pidfile" ] && [ -d "/proc/$(cat "$pidfile")" ]) && /etc/init.d/fastd stop
|
|
|
|
|
fi
|
|
|
|
|
fi
|
|
|
|
|
exit 0
|
|
|
|
|
else
|
|
|
|
|
echo "vpn-select: Hood file not found or empty!"
|
|
|
|
|
exit 1
|
|
|
|
|
# configure selected vpns
|
|
|
|
|
for key in $vpn_keys; do
|
|
|
|
|
json_select $key
|
|
|
|
|
json_get_var protocol protocol
|
|
|
|
|
[ "$protocol" = "$selected_protocol" ] && "${protocol}_addpeer"
|
|
|
|
|
json_select ".." # back to vpn
|
|
|
|
|
done
|
|
|
|
|
fi
|
|
|
|
|
|
|
|
|
|
# start/restart/stop vpnservices
|
|
|
|
|
for protocol in $supported_protocols; do
|
|
|
|
|
"${protocol}_start_stop"
|
|
|
|
|
done
|
|
|
|
|