mirror of
https://github.com/fosrl/olm.git
synced 2026-02-08 05:56:41 +00:00
93 lines
2.3 KiB
Go
93 lines
2.3 KiB
Go
//go:build (linux && !android) || freebsd
|
|
|
|
package dns
|
|
|
|
import (
|
|
"fmt"
|
|
"net/netip"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
// DetectBestConfigurator detects and returns the most appropriate DNS configurator for the system
|
|
// ifaceName is optional and only used for NetworkManager, systemd-resolved, and resolvconf
|
|
func DetectBestConfigurator(ifaceName string) (DNSConfigurator, error) {
|
|
// Try systemd-resolved first (most modern)
|
|
if IsSystemdResolvedAvailable() && ifaceName != "" {
|
|
if configurator, err := NewSystemdResolvedDNSConfigurator(ifaceName); err == nil {
|
|
return configurator, nil
|
|
}
|
|
}
|
|
|
|
// Try NetworkManager (common on desktops)
|
|
if IsNetworkManagerAvailable() && ifaceName != "" {
|
|
if configurator, err := NewNetworkManagerDNSConfigurator(ifaceName); err == nil {
|
|
return configurator, nil
|
|
}
|
|
}
|
|
|
|
// Try resolvconf (common on older systems)
|
|
if IsResolvconfAvailable() && ifaceName != "" {
|
|
if configurator, err := NewResolvconfDNSConfigurator(ifaceName); err == nil {
|
|
return configurator, nil
|
|
}
|
|
}
|
|
|
|
// Fall back to direct file manipulation
|
|
return NewFileDNSConfigurator()
|
|
}
|
|
|
|
// Helper functions for checking system state
|
|
|
|
// IsSystemdResolvedRunning checks if systemd-resolved is running
|
|
func IsSystemdResolvedRunning() bool {
|
|
// Check if stub resolver is configured
|
|
servers, err := readResolvConfDNS()
|
|
if err != nil {
|
|
return false
|
|
}
|
|
|
|
// systemd-resolved uses 127.0.0.53
|
|
stubAddr := netip.MustParseAddr("127.0.0.53")
|
|
for _, server := range servers {
|
|
if server == stubAddr {
|
|
return true
|
|
}
|
|
}
|
|
|
|
return false
|
|
}
|
|
|
|
// readResolvConfDNS reads DNS servers from /etc/resolv.conf
|
|
func readResolvConfDNS() ([]netip.Addr, error) {
|
|
content, err := os.ReadFile("/etc/resolv.conf")
|
|
if err != nil {
|
|
return nil, fmt.Errorf("read resolv.conf: %w", err)
|
|
}
|
|
|
|
var servers []netip.Addr
|
|
lines := strings.Split(string(content), "\n")
|
|
for _, line := range lines {
|
|
line = strings.TrimSpace(line)
|
|
if line == "" || strings.HasPrefix(line, "#") {
|
|
continue
|
|
}
|
|
|
|
if strings.HasPrefix(line, "nameserver") {
|
|
fields := strings.Fields(line)
|
|
if len(fields) >= 2 {
|
|
if addr, err := netip.ParseAddr(fields[1]); err == nil {
|
|
servers = append(servers, addr)
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
return servers, nil
|
|
}
|
|
|
|
// GetSystemDNS returns the current system DNS servers
|
|
func GetSystemDNS() ([]netip.Addr, error) {
|
|
return readResolvConfDNS()
|
|
}
|