From 17f046fc2a694a3a0d5ee983974da40d656f01ce Mon Sep 17 00:00:00 2001 From: Ycarus Date: Tue, 23 Jan 2018 15:38:27 +0100 Subject: [PATCH] Initial add of omr-tracker package --- omr-tracker/Makefile | 40 ++++++++ omr-tracker/files/bin/omr-tracker | 119 +++++++++++++++++++++++ omr-tracker/files/etc/config/omr-tracker | 10 ++ omr-tracker/files/etc/init.d/omr-tracker | 75 ++++++++++++++ 4 files changed, 244 insertions(+) create mode 100644 omr-tracker/Makefile create mode 100755 omr-tracker/files/bin/omr-tracker create mode 100644 omr-tracker/files/etc/config/omr-tracker create mode 100755 omr-tracker/files/etc/init.d/omr-tracker diff --git a/omr-tracker/Makefile b/omr-tracker/Makefile new file mode 100644 index 000000000..6ed23c623 --- /dev/null +++ b/omr-tracker/Makefile @@ -0,0 +1,40 @@ +# +# OpenMPTCProuter tracker is a modified version of OverTheBox tracker from OVH +# Copyright (C) 2017 Ycarus (Yannick Chabanois) +# +# This is free software, licensed under the GNU General Public License v3. +# See /LICENSE for more information. +# + +include $(TOPDIR)/rules.mk + +PKG_NAME:=omr-tracker +PKG_VERSION:=1.12 +PKG_RELEASE:=1 + +include $(INCLUDE_DIR)/package.mk + +define Package/$(PKG_NAME) + SECTION:=net + CATEGORY:=Network + TITLE:=OpenMPTCProuter tracker + DEPENDS:=+openmptcprouter +bind-dig + PKGARCH:=all +endef + +define Package/$(PKG_NAME)/description + A module to track OpenMPTCProuter connections +endef + +define Build/Compile +endef + +define Package/$(PKG_NAME)/conffiles +/etc/config/$(PKG_NAME) +endef + +define Package/$(PKG_NAME)/install + $(CP) ./files/* $(1)/ +endef + +$(eval $(call BuildPackage,$(PKG_NAME))) diff --git a/omr-tracker/files/bin/omr-tracker b/omr-tracker/files/bin/omr-tracker new file mode 100755 index 000000000..34bcbb834 --- /dev/null +++ b/omr-tracker/files/bin/omr-tracker @@ -0,0 +1,119 @@ +#!/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 +} + +_restart + +# main loop +while true; do + # setup tracker variables + OMR_TRACKER_DEVICE_IP= + OMR_TRACKER_DEVICE_GATEWAY= + 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 -o addr show "$OMR_TRACKER_DEVICE" | awk '{ print substr($4, 1, length($4) - 3) }') + OMR_TRACKER_DEVICE_IP=$(ip -4 -br addr ls dev "$OMR_TRACKER_DEVICE" | awk -F'[ /]+' '{print $3}') + + # execute specific tracker + if [ -n "$OMR_TRACKER_DEVICE_IP" ]; then + # setup loop variable + tries="$OMR_TRACKER_TRIES" + # loop until tries attempts have been reached + while [ "$tries" -gt 0 ]; do + ret=$(dig @"$OMR_TRACKER_HOST" \ + -b "$OMR_TRACKER_DEVICE_IP" \ + +time="$OMR_TRACKER_TIMEOUT" \ + +tries=1 \ + "$@" + ) && echo "$ret" | grep -sq "127.6.8.4" && { + OMR_TRACKER_LATENCY=$(echo "$ret" | awk '/Query time/{print $4}') + _update_rto "$OMR_TRACKER_LATENCY" + OMR_TRACKER_STATUS="OK" + break + } + tries=$((tries - 1)) + OMR_TRACKER_TIMEOUT=$((OMR_TRACKER_TIMEOUT * 2)) + done + fi + fi + + [ "$OMR_TRACKER_HOSTS" = "$initial_hosts" ] || [ "$OMR_TRACKER_STATUS" = "OK" ] && _post_tracking + [ "$OMR_TRACKER_STATUS" = "ERROR" ] && _restart + + sleep "$OMR_TRACKER_INTERVAL" +done diff --git a/omr-tracker/files/etc/config/omr-tracker b/omr-tracker/files/etc/config/omr-tracker new file mode 100644 index 000000000..c2c526419 --- /dev/null +++ b/omr-tracker/files/etc/config/omr-tracker @@ -0,0 +1,10 @@ +config defaults 'defaults' + list hosts '51.254.49.132' + list hosts '51.254.49.133' + option timeout '1' + option tries '3' + option interval '2' + option options 'tracker.overthebox.ovh' + +config rule_type 'tunnel' + option tries '5' diff --git a/omr-tracker/files/etc/init.d/omr-tracker b/omr-tracker/files/etc/init.d/omr-tracker new file mode 100755 index 000000000..a9a1a723a --- /dev/null +++ b/omr-tracker/files/etc/init.d/omr-tracker @@ -0,0 +1,75 @@ +#!/bin/sh /etc/rc.common +# shellcheck disable=SC2039 +# vim: set noexpandtab tabstop=4 shiftwidth=4 softtabstop=4 : + +# shellcheck disable=SC2034 +{ + START=90 + STOP=10 + USE_PROCD=1 +} + +_validate_section() { + local tmp_hosts=$hosts tmp_timeout=$timeout tmp_tries=$tries + local tmp_interval=$interval tmp_options=$options + + uci_validate_section omr-tracker "$1" "$2" \ + 'hosts:list(host)' \ + 'timeout:uinteger' \ + 'tries:uinteger' \ + 'interval:uinteger' \ + 'options:string' + + [ -z "$hosts" ] && hosts=$tmp_hosts + [ -z "$timeout" ] && timeout=$tmp_timeout + [ -z "$tries" ] && tries=$tmp_tries + [ -z "$interval" ] && interval=$tmp_interval + [ -z "$options" ] && options=$tmp_options +} + +_launch_tracker() { + case "$1" in + loopback|lan*|if0*|glorytun*) return;; + esac + + local interface_type + config_get interface_type "$1" type + + local hosts timeout tries interval options + _validate_section "defaults" "defaults" + _validate_section "rule_type" "$interface_type" + _validate_section "interface" "$1" + + local ifname ip4table + config_get ifname "$1" ifname + config_get multipath "$1" multipath + + [ -z "$ifname" ] || [ -z "$multipath" ] || [ "$multipath" = "off" ] && return + + procd_open_instance + # shellcheck disable=SC2086 + procd_set_param command /bin/omr-tracker "$1" $options + procd_append_param env "OMR_TRACKER_HOSTS=$hosts" + procd_append_param env "OMR_TRACKER_TIMEOUT=$timeout" + procd_append_param env "OMR_TRACKER_TRIES=$tries" + procd_append_param env "OMR_TRACKER_INTERVAL=$interval" + procd_append_param env "OMR_TRACKER_TABLE=$ip4table" + procd_append_param env "OMR_TRACKER_DEVICE=$ifname" + procd_set_param respawn 0 10 0 + procd_set_param stderr 1 + procd_close_instance +} + +start_service() { + config_load network + config_foreach _launch_tracker interface +} + +service_triggers() { + procd_add_reload_trigger omr-tracker network +} + +reload_service() { + stop + start +}