mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
fix bad logger usages patch darwin interface name patch darwin interface name, debugging make resetDNS check for static config on startup, optionally restoring static confiration as needed fix netmon logging
119 lines
2.7 KiB
Go
119 lines
2.7 KiB
Go
package ctrld
|
|
|
|
import (
|
|
"bufio"
|
|
"bytes"
|
|
"io"
|
|
"net"
|
|
"os"
|
|
"os/exec"
|
|
"path/filepath"
|
|
"runtime"
|
|
"strings"
|
|
)
|
|
|
|
var homedir string
|
|
|
|
// absHomeDir returns the absolute path to given filename using home directory as root dir.
|
|
func absHomeDir(filename string) string {
|
|
if homedir != "" {
|
|
return filepath.Join(homedir, filename)
|
|
}
|
|
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()
|
|
}
|
|
|
|
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.
|
|
func SavedStaticDnsSettingsFilePath(iface *net.Interface) string {
|
|
// The file is stored in the user home directory under a hidden file.
|
|
return absHomeDir(".dns_" + iface.Name)
|
|
}
|
|
|
|
// SavedStaticNameservers returns the stored static nameservers for the given interface.
|
|
func SavedStaticNameservers(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
|
|
}
|
|
|
|
func patchNetIfaceName(iface *net.Interface) (bool, error) {
|
|
b, err := exec.Command("networksetup", "-listnetworkserviceorder").Output()
|
|
if err != nil {
|
|
return false, err
|
|
}
|
|
|
|
patched := false
|
|
if name := networkServiceName(iface.Name, bytes.NewReader(b)); name != "" {
|
|
patched = true
|
|
iface.Name = name
|
|
}
|
|
return patched, nil
|
|
}
|
|
|
|
func networkServiceName(ifaceName string, r io.Reader) string {
|
|
scanner := bufio.NewScanner(r)
|
|
prevLine := ""
|
|
for scanner.Scan() {
|
|
line := scanner.Text()
|
|
if strings.Contains(line, "*") {
|
|
// Network services is disabled.
|
|
continue
|
|
}
|
|
if !strings.Contains(line, "Device: "+ifaceName) {
|
|
prevLine = line
|
|
continue
|
|
}
|
|
parts := strings.SplitN(prevLine, " ", 2)
|
|
if len(parts) == 2 {
|
|
return strings.TrimSpace(parts[1])
|
|
}
|
|
}
|
|
return ""
|
|
}
|