Prevent churn suppression from silencing labeled personal devices

Phone (c6:37:b0:b2:07:30) was cycling through arrivals/departures faster
than the 30-min churn window threshold, causing _check_churn to add its
IP to infrastructure_ips. All subsequent on_arrival calls were silently
dropped by the infrastructure IP check, so no ARRIVED alerts fired.

Two fixes:
- _check_churn: skip churn suppression entirely for MACs in device_labels
  or personal_devices — labeled devices are never infrastructure
- on_arrival already-known path: upgrade ip from '0.0.0.0'/'unknown'
  (ARP probe placeholder) to real IP when netlink delivers the actual address
This commit is contained in:
Cobra
2026-04-14 22:45:15 -04:00
parent 7154e2b295
commit d3da6ea89c
+8
View File
@@ -412,6 +412,10 @@ def _clear_recovery():
def _check_churn(mac: str, ip: str) -> bool:
"""Return True and suppress if this device churns too frequently."""
# Explicitly labeled personal devices are never churn-suppressed into infrastructure
with personal_lock:
if mac in device_labels or mac in personal_devices:
return False
now = time.time()
with _churn_lock:
events = _churn_tracker.get(mac, [])
@@ -1050,6 +1054,10 @@ def on_arrival(mac: str, ip: str, hostname: str = "") -> None:
# Device is already known
dev = known_devices[mac]
dev['last_seen'] = now
# Upgrade from ARP-probe placeholder to real IP
if dev.get('ip') in ('0.0.0.0', 'unknown') and ip not in ('0.0.0.0', 'unknown'):
dev['ip'] = ip
logging.debug(f"Updated {mac} IP from placeholder to {ip}")
# DHCP renewal dedup: if last_seen < 30 min, skip alert
if now - dev['first_seen'] < 1800: # 30 min