#!/bin/sh

# Copyright 2015-2024 Rivoreo

# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to
# deal in the Software without restriction, including without limitation the
# rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
# sell copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:

# The above copyright notice and this permission notice shall be included in
# all copies or substantial portions of the Software.

# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
# WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
# IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.


rand() {
	eval "$1=\"\`dd if=/dev/urandom count=1 bs=4 2> /dev/null | cksum\`\"" || return
	eval "[ -n \"\$$1\" ]" || return
	eval "$1=\${$1%% *}"
}

random_sleep() {
	local n
	rand n || return
	sleep $((n%($2-$1)+$1))
}

set -f

while true; do
	if ! interfaces="`wg show interfaces`"; then
		sleep 240
		continue
	fi
	set -- $interfaces
	min_sleep=$((3600/$#))
	[ $min_sleep -lt 30 ] && min_sleep=30
	max_sleep=$((115200/$#))
	[ $max_sleep -lt 810 ] && max_sleep=810
	have_matched_interface=
	for i in $@; do
		[ -f "/sys/class/net/$i/flags" ] || continue
		[ -f "/etc/wireguard/$i.conf" ] || continue
		flags="`cat \"/sys/class/net/$i/flags\"`" || continue
		[ $((flags&1)) = 1 ] || continue
		section=
		while read -r line; do case "$line" in
			\[[Ii][Nn][Tt][Ee][Rr][Ff][Aa][Cc][Ee]\]*)
				section=interface
				;;
			\[*\]*)
				section=
				;;
			?*=*)
				[ "$section" != interface ] && continue
				case "${line%%[ =	]*}" in
					[Ll][Ii][Ss][Tt][Ee][Nn][Pp][Oo][Rr][Tt])
						continue 2
						;;
				esac
				;;
		esac done < "/etc/wireguard/$i.conf"
		random_sleep 2 480
		if wg set "$i" listen-port 0; then
			have_matched_interface=1
			random_sleep $min_sleep $max_sleep
		fi
	done
	[ -z "$have_matched_interface" ] && sleep 120
done
