1
0
Fork 0
mirror of https://github.com/Ysurac/openmptcprouter-feeds.git synced 2025-02-15 03:51:51 +00:00
openmptcprouter-feeds/omr-tracker/files/bin/omr-tracker
2018-03-21 21:18:03 +01:00

200 lines
5.6 KiB
Bash
Executable file

#!/bin/sh
# shellcheck disable=SC1091,SC1090
# vim: set noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 :
[ -n "$1" ] || exit
. /lib/functions.sh
# retrieve args
OMR_TRACKER_INTERFACE="$1"
shift
# export vars
export OMR_TRACKER_INTERFACE
export OMR_TRACKER_HOST
export OMR_TRACKER_TIMEOUT
export OMR_TRACKER_STATUS
export OMR_TRACKER_DEVICE
export OMR_TRACKER_DEVICE_IP
export OMR_TRACKER_DEVICE_GATEWAY
dscp=56 # set DSCP CS7 (56) in outgoing packets
initial_hosts="$OMR_TRACKER_HOSTS"
initial_timeout="$OMR_TRACKER_TIMEOUT"
# set constants for rto updating
# we've changed the default values of the RFC to K=3 and beta=0.25 instead of K=4 and beta=0.125
# this allows us to lower the gap between rtt and rto when the latency increases quickly as our
# measurements are less frequent than the standard timeout computation of the TCP stack
_init_rto() {
srtt=
rttvar=
rto_init=$(( initial_timeout * 1000 ))
rto=$rto_init
}
# update rto as explained in rfc6298
# rto : retransmission timeout.
# rtt : round trip time
# rttvar : round trip time variance
# srtt : smoothed round trip time
# alpha : smoothing coeff for srtt
# beta : smoothing coeff for rttvar
# K : coeff to increase rttvar impact on rto computation
_update_rto() {
if [ -z "$srtt" ]; then
srtt=$1
rttvar=$(($1 / 2))
else
diff=$((srtt - $1))
rttvar=$(((75 * rttvar + 25 * (diff >= 0 ? diff : -diff)) / 100))
srtt=$(((75 * srtt + 25 * $1) / 100))
fi
rto=$((tmp = srtt + 3 * rttvar, tmp > rto_init ? tmp : rto_init))
}
_restart() {
OMR_TRACKER_HOST="${OMR_TRACKER_HOSTS%% *}"
[ "$OMR_TRACKER_HOST" = "$OMR_TRACKER_HOSTS" ] || {
OMR_TRACKER_HOSTS="${OMR_TRACKER_HOSTS#* } $OMR_TRACKER_HOST"
_init_rto
}
}
_post_tracking() {
for tracker_bin in /usr/share/omr/post-tracking.d/*; do
[ -x "$tracker_bin" ] && (
_log() {
logger -t "post-tracking-${tracker_bin##*/}" "$*"
}
. "$tracker_bin"
)
done
}
_ping() {
local host=$1
local deviceip=$2
local localip=$3
ret=$(ping "${host}" \
-I "${deviceip}" \
-W "$OMR_TRACKER_TIMEOUT" \
-c 1 \
-q
) && echo "$ret" | grep -sq "0% packet loss" && {
if [ "$localip" = "yes" ]; then
OMR_TRACKER_LATENCY=$(echo "$ret" | cut -d "/" -s -f4 | cut -d "." -f1)
_update_rto "$OMR_TRACKER_LATENCY"
fi
return
}
false
}
_httping() {
local host=$1
local deviceip=$2
local localip=$3
ret=$(httping "${host}" \
-y "${deviceip}" \
-t "$OMR_TRACKER_TIMEOUT" \
-c 1 \
-q
) && echo "$ret" | grep -sq "1 ok" && {
if [ "$localip" = "yes" ]; then
OMR_TRACKER_LATENCY=$(echo "$ret" | cut -d "/" -s -f5 | cut -d "." -f1)
_update_rto "$OMR_TRACKER_LATENCY"
fi
return
}
false
}
_dns() {
local host=$1
local deviceip=$2
ret=$(dig @"${host}" \
-b "${deviceip}" \
+time="$OMR_TRACKER_TIMEOUT" \
+tries=1 \
openmptcprouter.com
) && echo "$ret" | grep -sq "94.23.252.192" && {
OMR_TRACKER_LATENCY=$(echo "$ret" | awk '/Query time/{print $4}')
_update_rto "$OMR_TRACKER_LATENCY"
return
}
false
}
_none() {
return
}
_restart
# main loop
while true; do
# setup tracker variables
OMR_TRACKER_DEVICE_IP=
OMR_TRACKER_STATUS="ERROR"
OMR_TRACKER_LATENCY=
OMR_TRACKER_TIMEOUT=$((rto / 1000 + (rto % 1000 ? 1 : 0)))
if [ -d "/sys/class/net/$OMR_TRACKER_DEVICE" ]; then
# retrieve iface ip and gateway
OMR_TRACKER_DEVICE_IP=$(ip -4 -br addr ls dev "$OMR_TRACKER_DEVICE" | awk -F'[ /]+' '{print $3}')
#OMR_TRACKER_DEVICE_IP=$(ubus call network.interface.$OMR_TRACKER_INTERFACE status | jsonfilter -e '@["ipv4-address"][0].address' | tr -d "\n")
#if [ -z "$OMR_TRACKER_DEVICE_GATEWAY" ]; then
# OMR_TRACKER_DEVICE_GATEWAY=$(ip -4 r list dev "$OMR_TRACKER_DEVICE" | grep -v default | awk '/proto static/ {print $1}' | tr -d "\n")
#fi
if [ -z "$OMR_TRACKER_DEVICE_GATEWAY" ]; then
OMR_TRACKER_DEVICE_GATEWAY=$(uci -q get "network.$OMR_TRACKER_INTERFACE.gateway")
fi
if [ -z "$OMR_TRACKER_DEVICE_GATEWAY" ]; then
OMR_TRACKER_DEVICE_GATEWAY=$(ubus call network.interface.$OMR_TRACKER_INTERFACE status | jsonfilter -e '@.route[0].nexthop' | tr -d "\n")
fi
if [ -z "$OMR_TRACKER_DEVICE_GATEWAY" ]; then
OMR_TRACKER_DEVICE_GATEWAY=$(ubus call network.interface.$OMR_TRACKER_INTERFACE status | jsonfilter -e '@.inactive.route[0].nexthop' | tr -d "\n")
fi
# execute specific tracker
if [ -n "$OMR_TRACKER_DEVICE_IP" ] && [ -n "$OMR_TRACKER_DEVICE_GATEWAY" ]; then
_ping "$OMR_TRACKER_DEVICE_GATEWAY" "$OMR_TRACKER_DEVICE_IP" "no"
status=$?
if $(exit $status); then
# setup loop variable
tries="$OMR_TRACKER_TRIES"
ip route replace "$OMR_TRACKER_HOST" via "$OMR_TRACKER_DEVICE_GATEWAY" dev "$OMR_TRACKER_DEVICE" src "$OMR_TRACKER_DEVICE_IP"
# loop until tries attempts have been reached
while [ "$tries" -gt 0 ]; do
if [ "$OMR_TRACKER_TYPE" = "ping" ]; then
_ping "$OMR_TRACKER_HOST" "$OMR_TRACKER_DEVICE_IP" "yes"
status=$?
elif [ "$OMR_TRACKER_TYPE" = "httping" ]; then
_httping "$OMR_TRACKER_HOST" "$OMR_TRACKER_DEVICE_IP" "yes"
status=$?
elif [ "$OMR_TRACKER_TYPE" = "dns" ]; then
_dns "$OMR_TRACKER_HOST" "$OMR_TRACKER_DEVICE_IP" "yes"
status=$?
elif [ "$OMR_TRACKER_TYPE" = "none" ]; then
_none
status=$?
fi
if $(exit $status); then
OMR_TRACKER_STATUS="OK"
break
fi
tries=$((tries - 1))
OMR_TRACKER_TIMEOUT=$((OMR_TRACKER_TIMEOUT * 2))
done
ip route del "$OMR_TRACKER_HOST" via "$OMR_TRACKER_DEVICE_GATEWAY" dev "$OMR_TRACKER_DEVICE" src "$OMR_TRACKER_DEVICE_IP"
fi
fi
fi
[ "$OMR_TRACKER_HOSTS" = "$initial_hosts" ] || [ "$OMR_TRACKER_STATUS" = "OK" ] && _post_tracking
[ "$OMR_TRACKER_STATUS" = "ERROR" ] && _restart
sleep "$OMR_TRACKER_INTERVAL"
done