mirror of
https://github.com/Control-D-Inc/ctrld.git
synced 2026-10-12 01:58:46 +02:00
81 lines
2.9 KiB
Go
81 lines
2.9 KiB
Go
package ctrld
|
|
|
|
import (
|
|
"net/netip"
|
|
"slices"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
func TestScutilNameserversIPv6AndZones(t *testing.T) {
|
|
output := []byte(`DNS configuration
|
|
resolver #1
|
|
nameserver[0] : 192.0.2.53
|
|
nameserver[1] : 2001:db8::53
|
|
nameserver[2] : fe80::1%en0
|
|
nameserver[3] : 2001:db8::53
|
|
nameserver[4] : fe80::1%en1
|
|
nameserver[5] : 127.0.0.1
|
|
nameserver[6] : ::1
|
|
nameserver[7] : fe80::2%en0
|
|
nameserver[8] : not-an-address
|
|
search domain[0] : internal.example
|
|
`)
|
|
local := []netip.Addr{netip.MustParseAddr("127.0.0.1"), netip.MustParseAddr("::1"), netip.MustParseAddr("fe80::2%en0")}
|
|
got, err := parseScutilNameservers(output, local)
|
|
want := []string{"192.0.2.53", "2001:db8::53", "fe80::1%en0", "fe80::1%en1"}
|
|
if err != nil || !slices.Equal(got, want) {
|
|
t.Fatalf("nameservers=%v err=%v", got, err)
|
|
}
|
|
effective := initializeOsResolver(got)
|
|
r := newResolverWithNameserver(effective)
|
|
if !slices.Contains(*r.lanServers.Load(), "[fe80::1%en0]:53") || !slices.Contains(*r.lanServers.Load(), "[fe80::1%en1]:53") {
|
|
t.Fatalf("zones lost in effective resolver: %v", effective)
|
|
}
|
|
if !slices.Contains(*r.publicServers.Load(), "[2001:db8::53]:53") {
|
|
t.Fatalf("global IPv6 lost: %v", effective)
|
|
}
|
|
}
|
|
|
|
func TestScutilNameserversLocalExclusion(t *testing.T) {
|
|
for _, tt := range []struct {
|
|
name, local, server string
|
|
excluded bool
|
|
}{
|
|
{"unzoned link-local does not exclude scoped router", "fe80::1", "fe80::1%en0", false},
|
|
{"loopback link-local does not exclude router", "fe80::1%lo0", "fe80::1%en0", false},
|
|
{"other link does not exclude router", "fe80::1%en1", "fe80::1%en0", false},
|
|
{"same link excludes local address", "fe80::1%en0", "fe80::1%en0", true},
|
|
{"unzoned link-local matches unzoned local", "fe80::1", "fe80::1", true},
|
|
{"scoped local does not exclude unzoned candidate", "fe80::1%en0", "fe80::1", false},
|
|
{"global ignores zones", "2001:db8::1%en0", "2001:db8::1%en1", true},
|
|
{"loopback ignores zones", "::1%lo0", "::1", true},
|
|
{"IPv4 mapped local", "::ffff:192.0.2.1", "192.0.2.1", true},
|
|
{"IPv4 mapped candidate", "192.0.2.1", "::ffff:192.0.2.1", true},
|
|
{"IPv4 link-local mapped candidate", "169.254.1.1", "::ffff:169.254.1.1", true},
|
|
{"other global is retained", "2001:db8::1", "2001:db8::53", false},
|
|
} {
|
|
t.Run(tt.name, func(t *testing.T) {
|
|
got, err := parseScutilNameservers([]byte("nameserver[0] : "+tt.server+"\n"), []netip.Addr{netip.MustParseAddr(tt.local)})
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
var want []string
|
|
if !tt.excluded {
|
|
want = []string{tt.server}
|
|
}
|
|
if !slices.Equal(got, want) {
|
|
t.Fatalf("nameservers=%v, want %v", got, want)
|
|
}
|
|
})
|
|
}
|
|
}
|
|
|
|
func TestScutilNameserversRejectsPartialScan(t *testing.T) {
|
|
output := []byte("nameserver[0] : 192.0.2.53\n" + strings.Repeat("x", 128*1024))
|
|
got, err := parseScutilNameservers(output, nil)
|
|
if err == nil || got != nil {
|
|
t.Fatalf("partial scan accepted: %v, %v", got, err)
|
|
}
|
|
}
|