mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-02-03 22:18:39 +00:00
Unifying DNS from /etc/resolv.conf function
As part of v1.4.0 release, reading DNS from /etc/resolv.conf file is only available for Macos. However, there's no reason to prevent this function from working on other *nix systems. This commit unify the function to *nix, so it could be added as DNS source for Linux and Freebsd.
This commit is contained in:
committed by
Cuong Manh Le
parent
0c2cc00c4f
commit
c06c8aa859
@@ -10,7 +10,7 @@ import (
|
||||
)
|
||||
|
||||
func dnsFns() []dnsFn {
|
||||
return []dnsFn{dnsFromRIB}
|
||||
return []dnsFn{dnsFromResolvConf, dnsFromRIB}
|
||||
}
|
||||
|
||||
func dnsFromRIB() []string {
|
||||
|
||||
@@ -16,58 +16,12 @@ import (
|
||||
"time"
|
||||
|
||||
"tailscale.com/net/netmon"
|
||||
|
||||
"github.com/Control-D-Inc/ctrld/internal/resolvconffile"
|
||||
)
|
||||
|
||||
func dnsFns() []dnsFn {
|
||||
return []dnsFn{dnsFromResolvConf, getDNSFromScutil, getAllDHCPNameservers}
|
||||
}
|
||||
|
||||
// dnsFromResolvConf reads nameservers from /etc/resolv.conf
|
||||
func dnsFromResolvConf() []string {
|
||||
const (
|
||||
maxRetries = 10
|
||||
retryInterval = 100 * time.Millisecond
|
||||
)
|
||||
|
||||
regularIPs, loopbackIPs, _ := netmon.LocalAddresses()
|
||||
|
||||
var dns []string
|
||||
for attempt := 0; attempt < maxRetries; attempt++ {
|
||||
if attempt > 0 {
|
||||
time.Sleep(retryInterval)
|
||||
}
|
||||
|
||||
nss := resolvconffile.NameServers("")
|
||||
var localDNS []string
|
||||
seen := make(map[string]bool)
|
||||
|
||||
for _, ns := range nss {
|
||||
if ip := net.ParseIP(ns); ip != nil {
|
||||
// skip loopback IPs
|
||||
for _, v := range slices.Concat(regularIPs, loopbackIPs) {
|
||||
ipStr := v.String()
|
||||
if ip.String() == ipStr {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if !seen[ip.String()] {
|
||||
seen[ip.String()] = true
|
||||
localDNS = append(localDNS, ip.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we successfully read the file and found nameservers, return them
|
||||
if len(localDNS) > 0 {
|
||||
return localDNS
|
||||
}
|
||||
}
|
||||
|
||||
return dns
|
||||
}
|
||||
|
||||
func getDNSFromScutil() []string {
|
||||
logger := *ProxyLogger.Load()
|
||||
|
||||
|
||||
@@ -17,7 +17,7 @@ const (
|
||||
)
|
||||
|
||||
func dnsFns() []dnsFn {
|
||||
return []dnsFn{dns4, dns6, dnsFromSystemdResolver}
|
||||
return []dnsFn{dnsFromResolvConf, dns4, dns6, dnsFromSystemdResolver}
|
||||
}
|
||||
|
||||
func dns4() []string {
|
||||
|
||||
@@ -2,8 +2,63 @@
|
||||
|
||||
package ctrld
|
||||
|
||||
import "github.com/Control-D-Inc/ctrld/internal/resolvconffile"
|
||||
import (
|
||||
"net"
|
||||
"slices"
|
||||
"time"
|
||||
|
||||
func nameserversFromResolvconf() []string {
|
||||
"tailscale.com/net/netmon"
|
||||
|
||||
"github.com/Control-D-Inc/ctrld/internal/resolvconffile"
|
||||
)
|
||||
|
||||
// currentNameserversFromResolvconf returns the current nameservers set from /etc/resolv.conf file.
|
||||
func currentNameserversFromResolvconf() []string {
|
||||
return resolvconffile.NameServers("")
|
||||
}
|
||||
|
||||
// dnsFromResolvConf reads usable nameservers from /etc/resolv.conf file.
|
||||
// A nameserver is usable if it's not one of current machine's IP addresses
|
||||
// and loopback IP addresses.
|
||||
func dnsFromResolvConf() []string {
|
||||
const (
|
||||
maxRetries = 10
|
||||
retryInterval = 100 * time.Millisecond
|
||||
)
|
||||
|
||||
regularIPs, loopbackIPs, _ := netmon.LocalAddresses()
|
||||
|
||||
var dns []string
|
||||
for attempt := 0; attempt < maxRetries; attempt++ {
|
||||
if attempt > 0 {
|
||||
time.Sleep(retryInterval)
|
||||
}
|
||||
|
||||
nss := resolvconffile.NameServers("")
|
||||
var localDNS []string
|
||||
seen := make(map[string]bool)
|
||||
|
||||
for _, ns := range nss {
|
||||
if ip := net.ParseIP(ns); ip != nil {
|
||||
// skip loopback IPs
|
||||
for _, v := range slices.Concat(regularIPs, loopbackIPs) {
|
||||
ipStr := v.String()
|
||||
if ip.String() == ipStr {
|
||||
continue
|
||||
}
|
||||
}
|
||||
if !seen[ip.String()] {
|
||||
seen[ip.String()] = true
|
||||
localDNS = append(localDNS, ip.String())
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// If we successfully read the file and found nameservers, return them
|
||||
if len(localDNS) > 0 {
|
||||
return localDNS
|
||||
}
|
||||
}
|
||||
|
||||
return dns
|
||||
}
|
||||
|
||||
@@ -158,7 +158,7 @@ func getDNSServers(ctx context.Context) ([]string, error) {
|
||||
0, // DomainGuid - not needed
|
||||
0, // SiteName - not needed
|
||||
uintptr(flags), // Flags
|
||||
uintptr(unsafe.Pointer(&info))) // DomainControllerInfo - output
|
||||
uintptr(unsafe.Pointer(&info))) // DomainControllerInfo - output
|
||||
|
||||
if ret != 0 {
|
||||
switch ret {
|
||||
@@ -330,7 +330,8 @@ func getDNSServers(ctx context.Context) ([]string, error) {
|
||||
return ns, nil
|
||||
}
|
||||
|
||||
func nameserversFromResolvconf() []string {
|
||||
// currentNameserversFromResolvconf returns a nil slice of strings.
|
||||
func currentNameserversFromResolvconf() []string {
|
||||
return nil
|
||||
}
|
||||
|
||||
|
||||
@@ -584,7 +584,7 @@ func NewPrivateResolver() Resolver {
|
||||
}
|
||||
nss := *or.lanServers.Load()
|
||||
resolverMutex.Unlock()
|
||||
resolveConfNss := nameserversFromResolvconf()
|
||||
resolveConfNss := currentNameserversFromResolvconf()
|
||||
localRfc1918Addrs := Rfc1918Addresses()
|
||||
n := 0
|
||||
for _, ns := range nss {
|
||||
|
||||
Reference in New Issue
Block a user