mirror of
https://github.com/kiddin9/op-packages.git
synced 2026-11-04 11:03:56 +08:00
🤞 Sync 2026-09-27 22:16:29
This commit is contained in:
1 parent
8ede4a8320
commit
618f51e9dc
459 files changed
+44817
-2191
No files matched your search
@@ -0,0 +1,103 @@
|
||||
#!/bin/sh
|
||||
# shellcheck shell=dash
|
||||
# Triggered by dnsmasq on DHCP events (add/old/del).
|
||||
# Available env vars: ACTION, MACADDR, IPADDR, HOSTNAME
|
||||
#
|
||||
# Two consumers sit on "this MAC is new":
|
||||
# * the Telegram bot, which wants a notification
|
||||
# * the default-limit feature, which applies a rate limit or shape
|
||||
#
|
||||
# They are deliberately independent — either can be on without the other —
|
||||
# and they use different notions of "known". The bot has always keyed off its
|
||||
# own telegram_known.json, which the bot itself rewrites; the limiter uses the
|
||||
# seen-MAC ledger in trafficctl-fw.sh, because applying a limit is not an
|
||||
# action that may be repeated or misfired.
|
||||
|
||||
[ "$ACTION" = "add" ] || exit 0
|
||||
[ -n "$MACADDR" ] || exit 0
|
||||
|
||||
# ── Telegram notification ──────────────────────────────────────────────────
|
||||
|
||||
KNOWN_FILE="/etc/trafficctl/telegram_known.json"
|
||||
NOTIFY_FLAG="/tmp/trafficctl_tg_newdev"
|
||||
|
||||
if [ "$(uci -q get trafficctl.telegram.enabled)" = "1" ] &&
|
||||
! grep -q "\"$MACADDR\"" "$KNOWN_FILE" 2>/dev/null; then
|
||||
mkdir -p "$(dirname "$NOTIFY_FLAG")"
|
||||
# HOSTNAME comes from the dnsmasq dhcp hotplug environment (see header),
|
||||
# not a POSIX shell builtin — shellcheck's SC3028 is a false positive.
|
||||
# shellcheck disable=SC3028
|
||||
printf '%s\t%s\t%s\n' "$MACADDR" "${IPADDR:-?}" "${HOSTNAME:-unknown}" >> "$NOTIFY_FLAG"
|
||||
fi
|
||||
|
||||
# ── Default limit for a device seen for the first time ─────────────────────
|
||||
|
||||
[ "$(uci -q get trafficctl.newdevice.enabled 2>/dev/null)" = "1" ] || exit 0
|
||||
|
||||
LIMIT_KBIT=$(uci -q get trafficctl.newdevice.limit_kbit 2>/dev/null)
|
||||
[ -n "$LIMIT_KBIT" ] && [ "$LIMIT_KBIT" -gt 0 ] 2>/dev/null || exit 0
|
||||
|
||||
. /usr/local/bin/trafficctl-fw.sh
|
||||
|
||||
# The ledger decides what "new" means, so a run that has no ledger yet cannot
|
||||
# answer the question — and the wrong answer here limits every device on the
|
||||
# LAN as its lease renews.
|
||||
#
|
||||
# Seeding alone would not make that answer trustworthy: the seed reads the
|
||||
# leases and the neighbour table, and both can be thin or empty early in boot,
|
||||
# so a device missing from them would look new purely because the router had
|
||||
# not noticed it yet. The first pass therefore records the baseline and
|
||||
# applies nothing at all, whatever the seed happened to find.
|
||||
if ! tctl_seen_ready; then
|
||||
tctl_seen_seed
|
||||
tctl_seen_mark "$MACADDR"
|
||||
logger -t trafficctl "newdevice: seeded the seen-MAC ledger ($(tctl_seen_count) devices); no limit applied on this pass"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
tctl_seen_known "$MACADDR" && exit 0
|
||||
|
||||
# Mark BEFORE acting. A failure while applying the limit must not leave the
|
||||
# device unmarked, or every subsequent lease renewal retries — and each retry
|
||||
# is another chance to race with an operator setting a limit by hand.
|
||||
tctl_seen_mark "$MACADDR"
|
||||
|
||||
[ -n "$IPADDR" ] || {
|
||||
logger -t trafficctl "newdevice: $MACADDR is new but has no address yet; no limit applied"
|
||||
exit 0
|
||||
}
|
||||
|
||||
# Never override a limit somebody set deliberately.
|
||||
if tctl_has_limit "$IPADDR"; then
|
||||
logger -t trafficctl "newdevice: $IPADDR ($MACADDR) already has a limit; left alone"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
LIMIT_MODE=$(uci -q get trafficctl.newdevice.limit_mode 2>/dev/null)
|
||||
[ -n "$LIMIT_MODE" ] || LIMIT_MODE="limiter"
|
||||
|
||||
case "$LIMIT_MODE" in
|
||||
shaper)
|
||||
TCTL_VIA=newdevice TCTL_SRC=hotplug \
|
||||
/usr/local/bin/trafficctl-shape.sh add "$IPADDR" "$LIMIT_KBIT" \
|
||||
"shape_$IPADDR" >/dev/null 2>&1
|
||||
rc=$?
|
||||
;;
|
||||
*)
|
||||
TCTL_VIA=newdevice TCTL_SRC=hotplug \
|
||||
/usr/local/bin/trafficctl-ratelimit.sh "$IPADDR" "$LIMIT_KBIT" \
|
||||
"$(tctl_ratelimit_comment "$IPADDR")" >/dev/null 2>&1
|
||||
rc=$?
|
||||
;;
|
||||
esac
|
||||
|
||||
if [ "$rc" = "0" ]; then
|
||||
# trafficctl-ratelimit.sh writes its own activity-log entry and picks up
|
||||
# the via=newdevice/src=hotplug exported above, so the limiter path is
|
||||
# already recorded. trafficctl-shape.sh logs nothing, hence this branch.
|
||||
[ "$LIMIT_MODE" = "shaper" ] &&
|
||||
tctl_log "shape_set" "$IPADDR" \
|
||||
"${LIMIT_KBIT}kbit default for new device $MACADDR" "newdevice" "hotplug"
|
||||
else
|
||||
logger -t trafficctl "newdevice: failed to apply ${LIMIT_KBIT}kbit to $IPADDR ($MACADDR)"
|
||||
fi
|
||||
Reference in new issue
Block a user