#!/bin/sh
# Revoke the PPPoE dial lease. Runs every 5s. Only ever takes the WAN AWAY.
#
# vrrp-wan-reconcile is the single writer and runs every 30s; this is the
# watcher, and it exists because `may-dial` must be a LEASE, not a flag.
# ConditionPathExists is evaluated at START only -- it can prevent a dial, it can
# never revoke one. So if the reconciler stops running (timer masked, box wedged,
# someone stops it during maintenance) and the box is then demoted, nothing would
# ever hang up: it would keep the one ISP session while the new master tries to
# take it.
#
# Two conditions revoke, both biased the safe way:
#   - this box does not hold the management VIP
#   - the lease has not been renewed within LEASE_TTL (the reconciler is dead)
#
# Deliberately tiny: no config mode, no flock, no commit. It cannot wedge the
# router's configuration system, which is what earns it a 5s timer. Running at
# 5s rather than the reconciler's 30s is also what shrinks the double-dial
# window on a demotion from up to 30s down to about 5.

CONF=/config/vrrp-wan.conf
[ -r "$CONF" ] && . "$CONF"
VIP="${VRRP_WAN_VIP:-192.168.1.1}"
LEASE_TTL="${LEASE_TTL:-75}"
STATE=/run/vrrp-wan

revoke() {
    rm -f "$STATE/may-dial"
    systemctl is-active --quiet ppp@pppoe0 2>/dev/null || return 0
    logger -t vrrp-wan "GUARD: $1 -- hanging up pppoe0"
    systemctl stop ppp@pppoe0 2>/dev/null
}

if ! ip -4 -o addr show 2>/dev/null | grep -q " ${VIP}/"; then
    revoke "does not hold ${VIP}"
    exit 0
fi

# Holds the VIP, so it is entitled to dial -- but only while something is
# actively renewing the lease on its behalf.
if [ -f "$STATE/may-dial" ]; then
    age=$(( $(date +%s) - $(stat -c %Y "$STATE/may-dial" 2>/dev/null || echo 0) ))
    [ "$age" -gt "$LEASE_TTL" ] && revoke "lease stale (${age}s > ${LEASE_TTL}s; is vrrp-wan-reconcile.timer running?)"
fi
exit 0
