M24: LAN-Scanner Aktionen-Button, Traffic-Monitor+Sparkline, ARP-Fix
- Rechtsklick-Kontextmenü ersetzt durch sichtbaren "Aktionen"-Button je Geräte-Zeile (bisher nicht diskoverbar) - Live-Traffic pro Port (↓/↑, wiederverwendet InterfaceTrafficMonitor) plus kleines Sparkline-Liniendiagramm der letzten 10 Sekunden (Swift Charts, neuer TrafficSample-Typ) - Bug 34: ARP-Tabelle kann mehrere Zeilen für dieselbe MAC halten (reachable + stale/failed) — Auflösung bevorzugte bisher blind die zuletzt gesehene Zeile statt die erreichbare. Zwei Regressionstests. - Nebenbefund: dedizierte SSH-Dienste (Backup/NetworkTools/Traffic/ Update/FactoryReset) haben keinen eigenen Bestätigungspfad für einen neuen SSH-Host-Key, scheitern still solange REST verbindet — als offener Punkt dokumentiert. Alles live bestätigt. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
+78
@@ -1418,6 +1418,69 @@ Sektion einklappbar machen"). Zwei Schritte:
|
||||
`.listStyle(.sidebar)` an der `List` ergänzt, für den nativen
|
||||
macOS-Sidebar-Look. Live bestätigt ("sehr gut, bin sehr zufrieden").
|
||||
|
||||
**M24: LAN-Scanner — "Aktionen"-Button, Traffic-Monitor pro Port +
|
||||
Sparkline, ARP-Auflösungsbug gefixt** (2026-09-16). Drei Nutzerwünsche
|
||||
in einer Runde:
|
||||
|
||||
1. **"Aktionen"-Button statt Rechtsklick** ("der Rechtsklick ist nicht
|
||||
eindeutig erkennbar oder intuitiv, verlager bitte alle Funktionen
|
||||
des Rechtsklicks in den Button") — `.contextMenu` komplett entfernt,
|
||||
derselbe `deviceMenu(for:)`-Inhalt (Feste IP zuweisen/entfernen,
|
||||
Netzwerk-Tools, Rohdaten anzeigen) läuft jetzt über einen sichtbaren
|
||||
`Menu`-Button ("•••", Label "Aktionen") hinter jeder Geräte-Zeile.
|
||||
2. **Traffic-Monitor pro Port + Sparkline** ("ein Traffic-Monitor im
|
||||
LAN-Scanner", danach "ein kleines Liniendiagramm der letzten 10
|
||||
Sekunden ... pro Port") — pro-*Gerät* geht nicht ohne RouterOS-
|
||||
seitige Queue-Trees pro MAC (Nutzer selbst dagegen entschieden:
|
||||
"Traffic pro PORT statt pro Gerät"), daher denselben bereits
|
||||
gebauten `InterfaceTrafficMonitor` (Verbinden-Tab) wiederverwendet —
|
||||
`DevicesViewModel` bekam eigene `startTrafficPolling`/
|
||||
`stopTrafficPolling` (3s-Takt, gleiches Muster wie
|
||||
`ConnectViewModel`). Live-↓/↑-Zahl direkt neben jedem Port-Titel,
|
||||
plus neuer `TrafficSample`-Typ (`Core/Models/InterfaceTraffic.swift`)
|
||||
für eine nach echter Zeit (nicht fester Sample-Anzahl) auf 10
|
||||
Sekunden getrimmte Historie, gerendert als `Chart`/`LineMark`
|
||||
(Swift Charts, `TrafficSparkline` in `DevicesView.swift`) ohne
|
||||
Achsen — reiner Trend-Blick, die genaue Zahl steht ja daneben.
|
||||
3. **Bug 34, dabei live gefunden:** ein Laptop an `ether4` (Traffic
|
||||
sichtbar aktiv) erschien trotzdem unter "Unbekannter Port". Ursache:
|
||||
RouterOS' `/ip arp`-Tabelle hielt für dieselbe MAC-Adresse zwei
|
||||
Zeilen gleichzeitig — eine korrekte (`interface=ether4,
|
||||
status=reachable`) und eine veraltete (`interface=bridge,
|
||||
status=failed`, Überbleibsel von vor einem Netzwerkwechsel des
|
||||
Geräts). `DevicesViewModel.buildDevices` baute `arpInterfaceByMAC`
|
||||
bisher per blindem Überschreiben der letzten gesehenen Zeile auf —
|
||||
welche Zeile "gewann" hing von der Router-internen Tabellen-
|
||||
Reihenfolge ab, nicht von Korrektheit. Fix: `status=reachable`
|
||||
gewinnt jetzt immer gegen jeden anderen Status, bei Gleichstand ein
|
||||
konkreter Port gegen "bridge". Zwei neue Regressionstests
|
||||
(`testReachableArpRowWinsOverStaleFailedRowForSameMAC`/
|
||||
`...RegardlessOfOrder`, letzterer prüft explizit, dass der Fix nicht
|
||||
nur für die live beobachtete Reihenfolge zufällig funktioniert).
|
||||
|
||||
**Nebenbefund beim Debuggen von Punkt 2, kein Code-Bug, aber ein
|
||||
Betriebshinweis:** der Traffic-Monitor zeigte zunächst dauerhaft nichts
|
||||
an — `InterfaceTrafficMonitor.fetchTraffic` scheiterte still (`try?`)
|
||||
mit `untrustedSSHHostKey`. Ursache: der Router hatte seit dem letzten
|
||||
Werksreset (2026-09-15) einen neuen SSH-Host-Key, aber da die Haupt-
|
||||
verbindung dieser Session durchgehend über REST lief (M22-Fix), kam der
|
||||
bereits vorhandene "Unbekannter SSH-Schlüssel"-Bestätigungsdialog nie
|
||||
zum Zug — der lief bisher nur im SSH-*Fallback*-Pfad von
|
||||
`ConnectionService.connect`. Dedizierte SSH-Verbindungen (Backup,
|
||||
Netzwerk-Tools, Traffic-Monitor, Update, Werksreset) haben *keinen*
|
||||
eigenen UI-Bestätigungspfad für einen neuen Host-Key, scheitern bei
|
||||
einem Mismatch einfach still. Behoben durch `www-ssl` kurz deaktiviert
|
||||
(erzwingt den SSH-Fallback-Pfad in der Haupt-Verbindung), Nutzer hat
|
||||
den neuen Fingerprint einmalig über den bestehenden Dialog bestätigt
|
||||
(`SSHHostKeyTrustStore` ist ein einziger, über `UserDefaults.standard`
|
||||
geteilter Speicher — einmal dort vertraut gilt für jede dedizierte
|
||||
SSH-Verbindung mit), danach `www-ssl` wieder aktiviert. **Bleibt ein
|
||||
echter, noch offener Schwachpunkt:** falls der SSH-Host-Key sich künftig
|
||||
nochmal ändert (z.B. nach einem weiteren Werksreset) UND REST zu diesem
|
||||
Zeitpunkt bereits verbunden ist, würden dieselben dedizierten Dienste
|
||||
wieder wortlos nichts tun, ohne Hinweis auf die Ursache — siehe
|
||||
"Nächste Schritte".
|
||||
|
||||
## Nächste Schritte
|
||||
|
||||
1. ~~M16: restliche `RouterOSSchemaCatalog.swift`-Sektionen übersetzen~~,
|
||||
@@ -1576,6 +1639,21 @@ Sektion einklappbar machen"). Zwei Schritte:
|
||||
DHCP-Netzwerk-Optionen zwei Hops entfernt), Klick auf Pool/Adresse
|
||||
bleibt bei der 1-Hop-Regel — beides wie erwartet bestätigt
|
||||
("passt, live bestätigt").
|
||||
13. **Dedizierte SSH-Dienste scheitern still bei SSH-Host-Key-Mismatch,
|
||||
solange REST verbindet** (siehe M24-Nebenbefund oben) —
|
||||
`BackupService`/`NetworkToolsService`/`InterfaceTrafficMonitor`/
|
||||
`UpdateService`/`FactoryResetService` haben keinen eigenen
|
||||
UI-Bestätigungspfad für einen neuen SSH-Host-Key, nur
|
||||
`ConnectionService.connect`s SSH-*Fallback* zeigt den Dialog — und
|
||||
der wird nie erreicht, solange REST erfolgreich verbindet. Ein
|
||||
künftiger Host-Key-Wechsel (z.B. nach einem weiteren Werksreset)
|
||||
würde also wieder zu wortlos leeren Ergebnissen führen (leere
|
||||
Traffic-Anzeige, fehlschlagende Backups, etc.), ohne erkennbaren
|
||||
Grund in der UI. Mögliche Fixes: diese Dienste bei
|
||||
`untrustedSSHHostKey` einen eigenen Bestätigungsdialog zeigen
|
||||
lassen, oder `ConnectionService` beim Verbinden zusätzlich (nicht
|
||||
nur im Fallback-Fall) einmal den SSH-Host-Key prüfen/bestätigen
|
||||
lassen, unabhängig davon, ob REST erfolgreich war.
|
||||
|
||||
Gitea-Remote `origin` ist eingerichtet und wird laufend gepusht (siehe
|
||||
oben) — dieser Hinweis war veraltet, korrigiert am 2026-09-15.
|
||||
|
||||
Reference in New Issue
Block a user