mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-09-29 13:51:51 +02:00
all: fix OS resolver looping issue on Windows
By making dnsFromAdapter ignores DNS server which is the same IP address of the adapter. While at it, also changes OS resolver to use ctrld bootstrap DNS only if there's no available nameservers.
This commit is contained in:
1 parent
96085147ff
commit
19020a96bf
3 files changed
+32
-33
No files matched your search
+14
-2
@@ -507,7 +507,7 @@ func initCLI() {
|
|||||||
iface = runningIface(s)
|
iface = runningIface(s)
|
||||||
tasks := []task{
|
tasks := []task{
|
||||||
{s.Stop, false},
|
{s.Stop, false},
|
||||||
{func() error { p.resetDNS(); return nil }, false},
|
{func() error { resetDnsNoLog(p); return nil }, false},
|
||||||
{s.Start, true},
|
{s.Start, true},
|
||||||
}
|
}
|
||||||
if doTasks(tasks) {
|
if doTasks(tasks) {
|
||||||
@@ -887,7 +887,10 @@ NOTE: Uninstalling will set DNS to values provided by DHCP.`,
|
|||||||
sc := &service.Config{}
|
sc := &service.Config{}
|
||||||
*sc = *svcConfig
|
*sc = *svcConfig
|
||||||
sc.Executable = bin
|
sc.Executable = bin
|
||||||
s, err := newService(&prog{}, sc)
|
readConfig(false)
|
||||||
|
v.Unmarshal(&cfg)
|
||||||
|
p := &prog{router: router.New(&cfg, runInCdMode())}
|
||||||
|
s, err := newService(p, sc)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
mainLog.Load().Error().Msg(err.Error())
|
mainLog.Load().Error().Msg(err.Error())
|
||||||
return
|
return
|
||||||
@@ -931,6 +934,7 @@ NOTE: Uninstalling will set DNS to values provided by DHCP.`,
|
|||||||
}
|
}
|
||||||
tasks := []task{
|
tasks := []task{
|
||||||
{s.Stop, false},
|
{s.Stop, false},
|
||||||
|
{func() error { resetDnsNoLog(p); return nil }, false},
|
||||||
{s.Start, false},
|
{s.Start, false},
|
||||||
}
|
}
|
||||||
if doTasks(tasks) {
|
if doTasks(tasks) {
|
||||||
@@ -2541,3 +2545,11 @@ func runningIface(s service.Service) string {
|
|||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// resetDnsNoLog performs resetting DNS with logging disable.
|
||||||
|
func resetDnsNoLog(p *prog) {
|
||||||
|
lvl := zerolog.GlobalLevel()
|
||||||
|
zerolog.SetGlobalLevel(zerolog.Disabled)
|
||||||
|
p.resetDNS()
|
||||||
|
zerolog.SetGlobalLevel(lvl)
|
||||||
|
}
|
||||||
+13
-29
@@ -1,10 +1,8 @@
|
|||||||
package ctrld
|
package ctrld
|
||||||
|
|
||||||
import (
|
import (
|
||||||
"net"
|
|
||||||
"syscall"
|
"syscall"
|
||||||
|
|
||||||
"golang.org/x/sys/windows"
|
|
||||||
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
|
"golang.zx2c4.com/wireguard/windows/tunnel/winipcfg"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -19,37 +17,23 @@ func dnsFromAdapter() []string {
|
|||||||
}
|
}
|
||||||
ns := make([]string, 0, len(aas)*2)
|
ns := make([]string, 0, len(aas)*2)
|
||||||
seen := make(map[string]bool)
|
seen := make(map[string]bool)
|
||||||
do := func(addr windows.SocketAddress) {
|
addressMap := make(map[string]struct{})
|
||||||
sa, err := addr.Sockaddr.Sockaddr()
|
for _, aa := range aas {
|
||||||
if err != nil {
|
for a := aa.FirstUnicastAddress; a != nil; a = a.Next {
|
||||||
return
|
addressMap[a.Address.IP().String()] = struct{}{}
|
||||||
}
|
}
|
||||||
var ip net.IP
|
|
||||||
switch sa := sa.(type) {
|
|
||||||
case *syscall.SockaddrInet4:
|
|
||||||
ip = net.IPv4(sa.Addr[0], sa.Addr[1], sa.Addr[2], sa.Addr[3])
|
|
||||||
case *syscall.SockaddrInet6:
|
|
||||||
ip = make(net.IP, net.IPv6len)
|
|
||||||
copy(ip, sa.Addr[:])
|
|
||||||
if ip[0] == 0xfe && ip[1] == 0xc0 {
|
|
||||||
// Ignore these fec0/10 ones. Windows seems to
|
|
||||||
// populate them as defaults on its misc rando
|
|
||||||
// interfaces.
|
|
||||||
return
|
|
||||||
}
|
|
||||||
default:
|
|
||||||
return
|
|
||||||
|
|
||||||
}
|
|
||||||
if ip.IsLoopback() || seen[ip.String()] {
|
|
||||||
return
|
|
||||||
}
|
|
||||||
seen[ip.String()] = true
|
|
||||||
ns = append(ns, ip.String())
|
|
||||||
}
|
}
|
||||||
for _, aa := range aas {
|
for _, aa := range aas {
|
||||||
for dns := aa.FirstDNSServerAddress; dns != nil; dns = dns.Next {
|
for dns := aa.FirstDNSServerAddress; dns != nil; dns = dns.Next {
|
||||||
do(dns.Address)
|
ip := dns.Address.IP()
|
||||||
|
if ip == nil || ip.IsLoopback() || seen[ip.String()] {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, ok := addressMap[ip.String()]; ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
seen[ip.String()] = true
|
||||||
|
ns = append(ns, ip.String())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return ns
|
return ns
|
||||||
|
|||||||
+5
-2
@@ -39,10 +39,13 @@ var OsNameservers = defaultNameservers()
|
|||||||
// or is the Resolver used for ResolverTypeOS.
|
// or is the Resolver used for ResolverTypeOS.
|
||||||
var or = &osResolver{nameservers: OsNameservers}
|
var or = &osResolver{nameservers: OsNameservers}
|
||||||
|
|
||||||
// defaultNameservers returns OS nameservers plus ctrld bootstrap nameserver.
|
// defaultNameservers returns nameservers used by the OS.
|
||||||
|
// If no nameservers can be found, ctrld bootstrap nameserver will be used.
|
||||||
func defaultNameservers() []string {
|
func defaultNameservers() []string {
|
||||||
ns := nameservers()
|
ns := nameservers()
|
||||||
ns = append(ns, net.JoinHostPort(bootstrapDNS, "53"))
|
if len(ns) == 0 {
|
||||||
|
ns = append(ns, net.JoinHostPort(bootstrapDNS, "53"))
|
||||||
|
}
|
||||||
return ns
|
return ns
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in new issue
Block a user