14.04.2026 Update
This commit is contained in:
67
handlers/policy_sync.go
Normal file
67
handlers/policy_sync.go
Normal file
@@ -0,0 +1,67 @@
|
||||
package handlers
|
||||
|
||||
import (
|
||||
"sort"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"nano-router/clients"
|
||||
"nano-router/config"
|
||||
)
|
||||
|
||||
// StartPolicySync starts a background goroutine that re-applies nftables rules
|
||||
// whenever the ARP table changes for devices that have an explicit policy.
|
||||
// This ensures that policy (VPN / disabled) follows a device even when its IP
|
||||
// changes due to DHCP renewal or it connects on a different interface.
|
||||
func StartPolicySync(interval time.Duration) {
|
||||
go func() {
|
||||
// Give the binary time to fully start before the first check.
|
||||
time.Sleep(15 * time.Second)
|
||||
var lastSig string
|
||||
for {
|
||||
sig := policyARPSignature()
|
||||
if sig != lastSig {
|
||||
lastSig = sig
|
||||
applyBlockedFirewall()
|
||||
}
|
||||
time.Sleep(interval)
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
// policyARPSignature returns a stable string that captures the current mapping
|
||||
// of MAC→IPs only for devices that have an explicit (non-default) policy.
|
||||
// If the string changes between ticks, the firewall needs to be re-applied.
|
||||
func policyARPSignature() string {
|
||||
cfg, err := config.Load()
|
||||
if err != nil {
|
||||
return ""
|
||||
}
|
||||
|
||||
// Collect MACs with explicit policies.
|
||||
policyMACs := make(map[string]string) // mac → policy
|
||||
for _, kd := range cfg.KnownDevices {
|
||||
if kd.MAC != "" && kd.Policy != "" {
|
||||
policyMACs[kd.MAC] = kd.Policy
|
||||
}
|
||||
// Also treat legacy blocked=true as disabled policy.
|
||||
if kd.MAC != "" && kd.Blocked && kd.Policy == "" {
|
||||
policyMACs[kd.MAC] = "disabled"
|
||||
}
|
||||
}
|
||||
|
||||
if len(policyMACs) == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
arpByMAC := clients.GetARPIPsByMAC()
|
||||
|
||||
var parts []string
|
||||
for mac, policy := range policyMACs {
|
||||
ips := arpByMAC[mac]
|
||||
sort.Strings(ips)
|
||||
parts = append(parts, policy+":"+mac+"="+strings.Join(ips, ","))
|
||||
}
|
||||
sort.Strings(parts)
|
||||
return strings.Join(parts, "|")
|
||||
}
|
||||
Reference in New Issue
Block a user