Commit 3d147f7
committed
WAN stability detection and backoff to prevent SFE kernel errors (#517)
* Add WAN stability detection and backoff to prevent SFE kernel errors
When WAN interfaces flap (reboots, GPON swaps, ISP outages), wansteer's
health checker toggled state every ~6-10s, flushing SFE 3-6 times/min
while the gateway's own failover engine manipulated the same conntrack
entries. This race produced sfe_ipv4_remove_connection kernel errors.
Changes:
- Startup grace period: wait for WAN interfaces to be link-up and stable
before applying rules (prevents stale assumptions post-reboot)
- Instability detection: track state transition frequency per-WAN,
mark as "unstable" when transitions exceed threshold in window
- Backoff mode: when any WAN is unstable, suppress SFE/conntrack flushes
from health transitions and reconciliation drift detection. On recovery,
single forced flush + full rule reapply for clean state.
- SFE flush coalescing: minimum 10s interval between flushes, redundant
calls within cooldown are skipped
New config options (all with sensible defaults):
startup_grace_seconds (30), instability_threshold (3),
instability_window_seconds (300), backoff_recovery_seconds (60),
sfe_flush_cooldown_seconds (10)
* Fix reconciler false drift detection when WAN is down
expectedRuleCount() compared against the full config, but reapplyRules()
disables traffic classes targeting unhealthy WANs. This mismatch caused
the reconciler to detect "drift" every 30s while a WAN was down,
triggering unnecessary SFE flushes each time.
Fix: pass unhealthy WANs to expectedRuleCount so it skips the same
traffic classes that reapplyRules disables.
* Refactor: deduplicate onStateChange callback, remove closure capture
- Extract onHealthChange to a named function used by both initial setup
and SIGHUP reload (was duplicated inline)
- Move stability check into health tick case (remove separate ticker)
- Pass inBackoff explicitly through health checker instead of closing
over a variable from the main loop scope
* Show warning when deployed wansteer binary version is outdated
Compares the app's assembly version against the wansteer status JSON
version field after each status poll. Shows an alert-warning banner
in the status card when versions don't match.
Suppressed when both are dev, or either has a non-release version
string (alpha, pre-release, +metadata). Warns when one is dev and
the other is a tagged release, or when both are different tagged
releases.
* Stamp Go binary versions in macOS install script
The Mac install script was building cfspeedtest, uwnspeedtest, and
wansteer without passing -X main.version, so all binaries reported
"dev". Now uses git describe --tags --always to stamp the version,
matching what the MSI build and Dockerfile already do.
* Show wansteer version in daemon status metrics
* Fix status JSON parse failure from missing newline after cat
The SSH command concatenated the ---VERSION--- delimiter onto the
last line of the status JSON (cat doesn't guarantee a trailing
newline). This caused JsonSerializer to fail parsing every poll,
leaving _parsedStatus null and hiding uptime, rule count, WAN
health, and version metrics.
Fix: add 'echo' after cat to ensure a newline separator.
* Remove per-WAN health metrics from status card
* Fix uptime display timezone - use DateTimeOffset to preserve offset1 parent 223697d commit 3d147f7
9 files changed
Lines changed: 851 additions & 64 deletions
File tree
- scripts
- src
- NetworkOptimizer.Web
- Components/Pages
- Services
- wansteer
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
261 | 261 | | |
262 | 262 | | |
263 | 263 | | |
| 264 | + | |
| 265 | + | |
| 266 | + | |
| 267 | + | |
| 268 | + | |
264 | 269 | | |
265 | 270 | | |
266 | 271 | | |
| |||
271 | 276 | | |
272 | 277 | | |
273 | 278 | | |
274 | | - | |
| 279 | + | |
275 | 280 | | |
276 | 281 | | |
277 | 282 | | |
| |||
283 | 288 | | |
284 | 289 | | |
285 | 290 | | |
286 | | - | |
| 291 | + | |
287 | 292 | | |
288 | 293 | | |
289 | 294 | | |
290 | 295 | | |
291 | | - | |
| 296 | + | |
292 | 297 | | |
293 | 298 | | |
294 | 299 | | |
| |||
300 | 305 | | |
301 | 306 | | |
302 | 307 | | |
303 | | - | |
| 308 | + | |
304 | 309 | | |
305 | 310 | | |
306 | 311 | | |
| |||
Lines changed: 57 additions & 14 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
12 | 12 | | |
13 | 13 | | |
14 | 14 | | |
| 15 | + | |
| 16 | + | |
15 | 17 | | |
16 | 18 | | |
17 | 19 | | |
| |||
82 | 84 | | |
83 | 85 | | |
84 | 86 | | |
| 87 | + | |
| 88 | + | |
| 89 | + | |
| 90 | + | |
| 91 | + | |
| 92 | + | |
| 93 | + | |
85 | 94 | | |
86 | 95 | | |
87 | 96 | | |
| |||
99 | 108 | | |
100 | 109 | | |
101 | 110 | | |
102 | | - | |
103 | | - | |
104 | | - | |
105 | | - | |
106 | | - | |
107 | | - | |
108 | | - | |
109 | | - | |
110 | | - | |
111 | | - | |
112 | 111 | | |
113 | 112 | | |
| 113 | + | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
114 | 120 | | |
115 | 121 | | |
116 | 122 | | |
| |||
496 | 502 | | |
497 | 503 | | |
498 | 504 | | |
| 505 | + | |
| 506 | + | |
499 | 507 | | |
500 | 508 | | |
501 | 509 | | |
| |||
1066 | 1074 | | |
1067 | 1075 | | |
1068 | 1076 | | |
1069 | | - | |
| 1077 | + | |
1070 | 1078 | | |
1071 | 1079 | | |
1072 | | - | |
| 1080 | + | |
1073 | 1081 | | |
1074 | 1082 | | |
1075 | 1083 | | |
| |||
1082 | 1090 | | |
1083 | 1091 | | |
1084 | 1092 | | |
| 1093 | + | |
1085 | 1094 | | |
1086 | 1095 | | |
1087 | 1096 | | |
1088 | 1097 | | |
1089 | 1098 | | |
| 1099 | + | |
1090 | 1100 | | |
1091 | 1101 | | |
1092 | 1102 | | |
1093 | 1103 | | |
1094 | 1104 | | |
1095 | 1105 | | |
1096 | 1106 | | |
| 1107 | + | |
| 1108 | + | |
| 1109 | + | |
| 1110 | + | |
| 1111 | + | |
| 1112 | + | |
| 1113 | + | |
| 1114 | + | |
| 1115 | + | |
| 1116 | + | |
| 1117 | + | |
| 1118 | + | |
| 1119 | + | |
| 1120 | + | |
| 1121 | + | |
| 1122 | + | |
| 1123 | + | |
| 1124 | + | |
| 1125 | + | |
| 1126 | + | |
| 1127 | + | |
| 1128 | + | |
| 1129 | + | |
| 1130 | + | |
| 1131 | + | |
| 1132 | + | |
| 1133 | + | |
| 1134 | + | |
| 1135 | + | |
| 1136 | + | |
| 1137 | + | |
| 1138 | + | |
| 1139 | + | |
1097 | 1140 | | |
1098 | 1141 | | |
1099 | 1142 | | |
| |||
1217 | 1260 | | |
1218 | 1261 | | |
1219 | 1262 | | |
1220 | | - | |
1221 | | - | |
| 1263 | + | |
| 1264 | + | |
1222 | 1265 | | |
1223 | 1266 | | |
1224 | 1267 | | |
| |||
Lines changed: 1 addition & 1 deletion
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
48 | 48 | | |
49 | 49 | | |
50 | 50 | | |
51 | | - | |
| 51 | + | |
52 | 52 | | |
53 | 53 | | |
54 | 54 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
17 | 17 | | |
18 | 18 | | |
19 | 19 | | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
| 32 | + | |
| 33 | + | |
| 34 | + | |
| 35 | + | |
| 36 | + | |
| 37 | + | |
| 38 | + | |
| 39 | + | |
| 40 | + | |
20 | 41 | | |
21 | 42 | | |
22 | 43 | | |
| |||
90 | 111 | | |
91 | 112 | | |
92 | 113 | | |
| 114 | + | |
| 115 | + | |
| 116 | + | |
| 117 | + | |
| 118 | + | |
| 119 | + | |
| 120 | + | |
| 121 | + | |
| 122 | + | |
| 123 | + | |
| 124 | + | |
| 125 | + | |
| 126 | + | |
| 127 | + | |
| 128 | + | |
93 | 129 | | |
94 | 130 | | |
95 | 131 | | |
| |||
0 commit comments