Files
ctrld/staticdns.go
2025-10-09 16:52:21 +07:00

87 lines
2.3 KiB
Go

package ctrld
import (
"net"
"os"
"path/filepath"
"runtime"
"strings"
)
// AbsHomeDir returns the absolute path to given filename using home directory as root dir.
func AbsHomeDir(filename string) string {
dir, err := UserHomeDir()
if err != nil {
return filename
}
return filepath.Join(dir, filename)
}
func dirWritable(dir string) (bool, error) {
f, err := os.CreateTemp(dir, "")
if err != nil {
return false, err
}
defer os.Remove(f.Name())
return true, f.Close()
}
// UserHomeDir returns the home directory for user who is running ctrld.
func UserHomeDir() (string, error) {
// viper will expand for us.
if runtime.GOOS == "windows" {
// If we're on windows, use the install path for this.
exePath, err := os.Executable()
if err != nil {
return "", err
}
return filepath.Dir(exePath), nil
}
dir := "/etc/controld"
if err := os.MkdirAll(dir, 0750); err != nil {
return os.UserHomeDir() // fallback to user home directory
}
if ok, _ := dirWritable(dir); !ok {
return os.UserHomeDir()
}
return dir, nil
}
// SavedStaticDnsSettingsFilePath returns the file path where the static DNS settings
// for the provided interface are saved.
//
// The caller must ensure iface is non-nil.
func SavedStaticDnsSettingsFilePath(iface *net.Interface) string {
// The file is stored in the user home directory under a hidden file.
return AbsHomeDir(".dns_" + iface.Name)
}
// SavedStaticNameserversAndPath returns the stored static nameservers for the given interface,
// and the absolute path to file that stored the settings.
//
// The caller must ensure iface is non-nil.
func SavedStaticNameserversAndPath(iface *net.Interface) ([]string, string) {
file := SavedStaticDnsSettingsFilePath(iface)
data, err := os.ReadFile(file)
if err != nil || len(data) == 0 {
return nil, file
}
saveValues := strings.Split(string(data), ",")
var ns []string
for _, v := range saveValues {
// Skip any IP that is loopback
if ip := net.ParseIP(v); ip != nil && ip.IsLoopback() {
continue
}
ns = append(ns, v)
}
return ns, file
}
// SavedStaticNameservers is like SavedStaticNameserversAndPath, but only returns the static nameservers.
func SavedStaticNameservers(iface *net.Interface) []string {
nss, _ := SavedStaticNameserversAndPath(iface)
return nss
}