Harden resolver and expand traffic runtime controls

This commit is contained in:
beckline
2026-02-24 00:17:46 +03:00
parent 89eaaf3f23
commit 50518a641d
18 changed files with 2048 additions and 181 deletions

View File

@@ -9,6 +9,7 @@ import (
"os"
"strings"
"syscall"
"time"
)
// ---------------------------------------------------------------------
@@ -263,6 +264,10 @@ func handleRoutesCacheRestore(w http.ResponseWriter, r *http.Request) {
// RU: `routesClear` - содержит основную логику для routes clear.
// ---------------------------------------------------------------------
func routesClear() cmdResult {
return withRoutesOpLock("routes clear", routesClearUnlocked)
}
func routesClearUnlocked() cmdResult {
cacheMeta, cacheErr := saveRoutesClearCache()
stdout, stderr, _, err := runCommand("ip", "rule", "show")
@@ -273,6 +278,11 @@ func routesClear() cmdResult {
_, _, _, _ = runCommand("ip", "route", "flush", "table", routesTableName())
_, _, _, _ = runCommand("nft", "flush", "set", "inet", "agvpn", "agvpn4")
_, _, _, _ = runCommand("nft", "flush", "set", "inet", "agvpn", "agvpn_dyn4")
iface := strings.TrimSpace(cacheMeta.Iface)
if iface == "" {
iface, _ = resolveTrafficIface(loadTrafficModeState().PreferredIface)
}
_ = writeStatusSnapshot(0, iface)
res := cmdResult{
OK: true,
@@ -297,6 +307,50 @@ func routesClear() cmdResult {
return res
}
func withRoutesOpLock(opName string, fn func() cmdResult) cmdResult {
lock, err := os.OpenFile(lockFile, os.O_CREATE|os.O_RDWR, 0o644)
if err != nil {
return cmdResult{
OK: false,
Message: fmt.Sprintf("%s lock open error: %v", opName, err),
}
}
defer lock.Close()
if err := syscall.Flock(int(lock.Fd()), syscall.LOCK_EX|syscall.LOCK_NB); err != nil {
return cmdResult{
OK: false,
Message: fmt.Sprintf("%s skipped: routes operation already running", opName),
}
}
defer syscall.Flock(int(lock.Fd()), syscall.LOCK_UN)
return fn()
}
func writeStatusSnapshot(ipCount int, iface string) error {
if ipCount < 0 {
ipCount = 0
}
iface = strings.TrimSpace(iface)
if iface == "" {
iface = "-"
}
st := Status{
Timestamp: time.Now().UTC().Format(time.RFC3339),
IPCount: ipCount,
DomainCount: countDomainsFromMap(lastIPsMapPath),
Iface: iface,
Table: routesTableName(),
Mark: MARK,
}
data, err := json.MarshalIndent(st, "", " ")
if err != nil {
return err
}
return os.WriteFile(statusFilePath, data, 0o644)
}
// ---------------------------------------------------------------------
// policy route
// ---------------------------------------------------------------------