Harden resolver and expand traffic runtime controls
This commit is contained in:
@@ -25,7 +25,7 @@ import (
|
||||
// RU: привязаны к конкретному systemd unit/cgroup.
|
||||
|
||||
const (
|
||||
trafficAppProfilesDefaultTTLSec = 24 * 60 * 60
|
||||
trafficAppProfilesDefaultTTLSec = 0 // 0 = persistent runtime mark policy
|
||||
)
|
||||
|
||||
var trafficAppProfilesMu sync.Mutex
|
||||
@@ -295,6 +295,11 @@ func loadTrafficAppProfilesState() trafficAppProfilesState {
|
||||
st.Profiles[i].AppKey = canon
|
||||
changed = true
|
||||
}
|
||||
st.Profiles[i].Target = strings.ToLower(strings.TrimSpace(st.Profiles[i].Target))
|
||||
}
|
||||
if deduped, dedupChanged := dedupeTrafficAppProfiles(st.Profiles); dedupChanged {
|
||||
st.Profiles = deduped
|
||||
changed = true
|
||||
}
|
||||
if changed {
|
||||
_ = saveTrafficAppProfilesState(st)
|
||||
@@ -302,6 +307,89 @@ func loadTrafficAppProfilesState() trafficAppProfilesState {
|
||||
return st
|
||||
}
|
||||
|
||||
func dedupeTrafficAppProfiles(in []TrafficAppProfile) ([]TrafficAppProfile, bool) {
|
||||
if len(in) <= 1 {
|
||||
return in, false
|
||||
}
|
||||
|
||||
out := make([]TrafficAppProfile, 0, len(in))
|
||||
byID := map[string]int{}
|
||||
byAppTarget := map[string]int{}
|
||||
changed := false
|
||||
|
||||
for _, raw := range in {
|
||||
p := raw
|
||||
p.ID = strings.TrimSpace(p.ID)
|
||||
p.Target = strings.ToLower(strings.TrimSpace(p.Target))
|
||||
p.AppKey = canonicalizeAppKey(p.AppKey, p.Command)
|
||||
|
||||
if p.ID == "" {
|
||||
changed = true
|
||||
continue
|
||||
}
|
||||
if p.Target != "vpn" && p.Target != "direct" {
|
||||
p.Target = "vpn"
|
||||
changed = true
|
||||
}
|
||||
|
||||
if idx, ok := byID[p.ID]; ok {
|
||||
if preferTrafficProfile(p, out[idx]) {
|
||||
out[idx] = p
|
||||
}
|
||||
changed = true
|
||||
continue
|
||||
}
|
||||
|
||||
if p.AppKey != "" {
|
||||
key := p.Target + "|" + p.AppKey
|
||||
if idx, ok := byAppTarget[key]; ok {
|
||||
if preferTrafficProfile(p, out[idx]) {
|
||||
byID[p.ID] = idx
|
||||
out[idx] = p
|
||||
}
|
||||
changed = true
|
||||
continue
|
||||
}
|
||||
byAppTarget[key] = len(out)
|
||||
}
|
||||
|
||||
byID[p.ID] = len(out)
|
||||
out = append(out, p)
|
||||
}
|
||||
return out, changed
|
||||
}
|
||||
|
||||
func preferTrafficProfile(cand, cur TrafficAppProfile) bool {
|
||||
cu := strings.TrimSpace(cand.UpdatedAt)
|
||||
ou := strings.TrimSpace(cur.UpdatedAt)
|
||||
if cu != ou {
|
||||
if cu == "" {
|
||||
return false
|
||||
}
|
||||
if ou == "" {
|
||||
return true
|
||||
}
|
||||
return cu > ou
|
||||
}
|
||||
|
||||
cc := strings.TrimSpace(cand.CreatedAt)
|
||||
oc := strings.TrimSpace(cur.CreatedAt)
|
||||
if cc != oc {
|
||||
if cc == "" {
|
||||
return false
|
||||
}
|
||||
if oc == "" {
|
||||
return true
|
||||
}
|
||||
return cc > oc
|
||||
}
|
||||
|
||||
if strings.TrimSpace(cand.Command) != "" && strings.TrimSpace(cur.Command) == "" {
|
||||
return true
|
||||
}
|
||||
return false
|
||||
}
|
||||
|
||||
func saveTrafficAppProfilesState(st trafficAppProfilesState) error {
|
||||
st.Version = 1
|
||||
st.UpdatedAt = time.Now().UTC().Format(time.RFC3339)
|
||||
|
||||
Reference in New Issue
Block a user