From a7b094a1284fd1fa9c8aaf84598e5ee12ed6041d Mon Sep 17 00:00:00 2001
From: Matthias Nott <mnott@mnsoft.org>
Date: Wed, 25 Mar 2026 11:18:25 +0100
Subject: [PATCH] fix: cache discovered host to prevent repeated subnet scan floods
---
lib/services/mqtt_service.dart | 36 ++++++++++++++++++++----------------
1 files changed, 20 insertions(+), 16 deletions(-)
diff --git a/lib/services/mqtt_service.dart b/lib/services/mqtt_service.dart
index 60930a5..b74b7e1 100644
--- a/lib/services/mqtt_service.dart
+++ b/lib/services/mqtt_service.dart
@@ -44,6 +44,7 @@
ConnectionStatus _status = ConnectionStatus.disconnected;
bool _intentionalClose = false;
String? _clientId;
+ String? _lastDiscoveredHost;
StreamSubscription? _updatesSub;
// Message deduplication
@@ -104,12 +105,15 @@
final clientId = await _getClientId();
- // Connection order: local → Bonjour → VPN → remote
+ // Connection order: local → cached discovery → Bonjour/scan → VPN → remote
final attempts = <MapEntry<String, int>>[]; // host → timeout ms
if (config.localHost != null && config.localHost!.isNotEmpty) {
attempts.add(MapEntry(config.localHost!, 2500));
}
- // Bonjour placeholder — inserted dynamically below
+ // Try cached discovered host before scanning again
+ if (_lastDiscoveredHost != null) {
+ attempts.add(MapEntry(_lastDiscoveredHost!, 3000));
+ }
if (config.vpnHost != null && config.vpnHost!.isNotEmpty) {
attempts.add(MapEntry(config.vpnHost!, 3000));
}
@@ -118,7 +122,6 @@
}
_mqttLog('MQTT: attempts=${attempts.map((e) => e.key).join(", ")} port=${config.port}');
- // Try configured local host first
for (final attempt in attempts) {
if (_intentionalClose) return;
_mqttLog('MQTT: trying ${attempt.key}:${config.port}');
@@ -127,21 +130,22 @@
} catch (e) {
_mqttLog('MQTT: ${attempt.key} error=$e');
}
+ }
- // After local host fails, try Bonjour discovery before VPN/remote
- if (attempt.key == config.localHost && !_intentionalClose) {
- _mqttLog('MQTT: trying Bonjour discovery...');
- final bonjourHost = await _discoverViaMdns();
- if (bonjourHost != null && !_intentionalClose) {
- _mqttLog('MQTT: Bonjour found $bonjourHost');
- try {
- if (await _tryConnect(bonjourHost, clientId, timeout: 3000)) return;
- } catch (e) {
- _mqttLog('MQTT: Bonjour host $bonjourHost error=$e');
- }
- } else {
- _mqttLog('MQTT: Bonjour discovery returned nothing');
+ // All configured hosts failed — try Bonjour/subnet scan (only once, not on retry)
+ if (_lastDiscoveredHost == null && !_intentionalClose) {
+ _mqttLog('MQTT: trying Bonjour/subnet discovery...');
+ final discovered = await _discoverViaMdns();
+ if (discovered != null && !_intentionalClose) {
+ _lastDiscoveredHost = discovered;
+ _mqttLog('MQTT: discovered $discovered, connecting...');
+ try {
+ if (await _tryConnect(discovered, clientId, timeout: 3000)) return;
+ } catch (e) {
+ _mqttLog('MQTT: discovered host $discovered error=$e');
}
+ } else {
+ _mqttLog('MQTT: discovery returned nothing');
}
}
--
Gitblit v1.3.1