117 lines
2.8 KiB
Go
117 lines
2.8 KiB
Go
package app
|
|
|
|
import (
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
func smartDNSRuntimeEnabledFromConfig() (bool, error) {
|
|
data, err := os.ReadFile(smartdnsMainConfig)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
for _, raw := range strings.Split(string(data), "\n") {
|
|
trimmed := strings.TrimSpace(raw)
|
|
if trimmed == "" || strings.HasPrefix(trimmed, "#") {
|
|
continue
|
|
}
|
|
if strings.Contains(trimmed, "nftset") &&
|
|
strings.Contains(trimmed, "domain-set:agvpn_wild") &&
|
|
strings.Contains(trimmed, "agvpn_dyn4") {
|
|
return true, nil
|
|
}
|
|
}
|
|
return false, nil
|
|
}
|
|
|
|
func normalizeSmartDNSMainConfig(content string, enabled bool) string {
|
|
normalized := strings.ReplaceAll(content, "\r\n", "\n")
|
|
lines := strings.Split(normalized, "\n")
|
|
out := make([]string, 0, len(lines)+4)
|
|
|
|
seenDomain := false
|
|
seenNftset := false
|
|
|
|
isDomainLine := func(raw string) bool {
|
|
t := strings.TrimSpace(raw)
|
|
if strings.HasPrefix(t, "#") {
|
|
t = strings.TrimSpace(strings.TrimPrefix(t, "#"))
|
|
}
|
|
return strings.HasPrefix(t, "domain-set ") &&
|
|
strings.Contains(t, "-name agvpn_wild") &&
|
|
strings.Contains(t, "/etc/selective-vpn/smartdns.conf")
|
|
}
|
|
isNftsetLine := func(raw string) bool {
|
|
t := strings.TrimSpace(raw)
|
|
if strings.HasPrefix(t, "#") {
|
|
t = strings.TrimSpace(strings.TrimPrefix(t, "#"))
|
|
}
|
|
return strings.HasPrefix(t, "nftset ") &&
|
|
strings.Contains(t, "domain-set:agvpn_wild") &&
|
|
strings.Contains(t, "agvpn_dyn4")
|
|
}
|
|
|
|
for _, raw := range lines {
|
|
switch {
|
|
case isDomainLine(raw):
|
|
if !seenDomain {
|
|
if enabled {
|
|
out = append(out, smartdnsRuntimeDomainSetLine)
|
|
} else {
|
|
out = append(out, "# "+smartdnsRuntimeDomainSetLine)
|
|
}
|
|
seenDomain = true
|
|
}
|
|
case isNftsetLine(raw):
|
|
if !seenNftset {
|
|
if enabled {
|
|
out = append(out, smartdnsRuntimeNftsetLine)
|
|
} else {
|
|
out = append(out, "# "+smartdnsRuntimeNftsetLine)
|
|
}
|
|
seenNftset = true
|
|
}
|
|
default:
|
|
out = append(out, raw)
|
|
}
|
|
}
|
|
|
|
if enabled && (!seenDomain || !seenNftset) {
|
|
if len(out) > 0 && strings.TrimSpace(out[len(out)-1]) != "" {
|
|
out = append(out, "")
|
|
}
|
|
if !seenDomain {
|
|
out = append(out, smartdnsRuntimeDomainSetLine)
|
|
}
|
|
if !seenNftset {
|
|
out = append(out, smartdnsRuntimeNftsetLine)
|
|
}
|
|
}
|
|
|
|
rendered := strings.Join(out, "\n")
|
|
if !strings.HasSuffix(rendered, "\n") {
|
|
rendered += "\n"
|
|
}
|
|
return rendered
|
|
}
|
|
|
|
func applySmartDNSRuntimeConfig(enabled bool) (bool, error) {
|
|
data, err := os.ReadFile(smartdnsMainConfig)
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
current := strings.ReplaceAll(string(data), "\r\n", "\n")
|
|
next := normalizeSmartDNSMainConfig(current, enabled)
|
|
if next == current {
|
|
return false, nil
|
|
}
|
|
tmp := smartdnsMainConfig + ".tmp"
|
|
if err := os.WriteFile(tmp, []byte(next), 0o644); err != nil {
|
|
return false, err
|
|
}
|
|
if err := os.Rename(tmp, smartdnsMainConfig); err != nil {
|
|
return false, err
|
|
}
|
|
return true, nil
|
|
}
|