92 lines
2.6 KiB
Go
92 lines
2.6 KiB
Go
package app
|
|
|
|
import (
|
|
"fmt"
|
|
"os"
|
|
)
|
|
|
|
// ---------------------------------------------------------------------
|
|
// основной routesUpdate
|
|
// ---------------------------------------------------------------------
|
|
|
|
// EN: Core selective-routes orchestration pipeline.
|
|
// EN: This unit prepares policy routing, nftables objects, domain expansion,
|
|
// EN: resolver execution, status artifacts, and GUI-facing progress events.
|
|
// RU: Основной orchestration-пайплайн selective-routes.
|
|
// RU: Модуль готовит policy routing, nftables-объекты, расширение доменов,
|
|
// RU: запуск резолвера, статусные артефакты и события прогресса для GUI.
|
|
|
|
// ---------------------------------------------------------------------
|
|
// EN: `routesUpdate` contains core logic for routes update.
|
|
// RU: `routesUpdate` - содержит основную логику для routes update.
|
|
// ---------------------------------------------------------------------
|
|
func routesUpdate(iface string) cmdResult {
|
|
logp := func(format string, args ...any) {
|
|
appendTraceLine("routes", fmt.Sprintf(format, args...))
|
|
}
|
|
heartbeat := func() {
|
|
_ = os.WriteFile(heartbeatFile, []byte{}, 0o644)
|
|
}
|
|
|
|
res := cmdResult{OK: false}
|
|
|
|
iface = normalizePreferredIface(iface)
|
|
if iface == "" {
|
|
iface, _ = resolveTrafficIface(loadTrafficModeState().PreferredIface)
|
|
}
|
|
if iface == "" {
|
|
logp("no active vpn iface, exit 0")
|
|
res.OK = true
|
|
res.Message = "interface not found, skipped"
|
|
return res
|
|
}
|
|
|
|
skip, message, err := routesUpdateStagePreflight(iface, logp, heartbeat)
|
|
if err != nil {
|
|
res.Message = message
|
|
return res
|
|
}
|
|
if skip {
|
|
res.OK = true
|
|
res.Message = message
|
|
return res
|
|
}
|
|
|
|
if err := routesUpdateStagePolicy(iface, logp); err != nil {
|
|
res.Message = err.Error()
|
|
return res
|
|
}
|
|
heartbeat()
|
|
|
|
routesUpdateStageNftBase(iface)
|
|
heartbeat()
|
|
|
|
resolveStage, err := routesUpdateStageResolve(logp, heartbeat)
|
|
if err != nil {
|
|
res.Message = err.Error()
|
|
return res
|
|
}
|
|
defer resolveStage.cleanup()
|
|
|
|
if err := routesUpdateStagePopulateNFT(resolveStage, logp, heartbeat); err != nil {
|
|
res.Message = err.Error()
|
|
return res
|
|
}
|
|
|
|
if err := routesUpdateStageArtifacts(iface, resolveStage, heartbeat); err != nil {
|
|
res.Message = err.Error()
|
|
return res
|
|
}
|
|
|
|
res.OK = true
|
|
res.Message = fmt.Sprintf(
|
|
"update done: domains=%d unique_ips=%d direct_ips=%d wildcard_ips=%d",
|
|
len(resolveStage.domains),
|
|
resolveStage.ipCount,
|
|
resolveStage.directIPCount,
|
|
resolveStage.wildcardIPCount,
|
|
)
|
|
res.ExitCode = resolveStage.ipCount
|
|
return res
|
|
}
|